Skip to content

Commit

Permalink
Merge pull request #2992 from christianvogt/model-reg-proxy
Browse files Browse the repository at this point in the history
refactor model registry proxy onto proxy util
  • Loading branch information
openshift-merge-bot[bot] authored Jul 16, 2024
2 parents 48b04aa + 11f01ed commit 13b5562
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 72 deletions.
48 changes: 17 additions & 31 deletions backend/src/routes/api/service/modelregistry/index.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,18 @@
import httpProxy from '@fastify/http-proxy';
import { KubeFastifyInstance } from '../../../../types';
import { DEV_MODE, MODEL_REGISTRY_NAMESPACE } from '../../../../utils/constants';
import { getParam, setParam } from '../../../../utils/proxy';
import { MODEL_REGISTRY_NAMESPACE } from '../../../../utils/constants';
import { proxyService } from '../../../../utils/proxy';

export default async (fastify: KubeFastifyInstance): Promise<void> => {
fastify.register(httpProxy, {
upstream: '',
prefix: '/:name',
rewritePrefix: '',
replyOptions: {
// preHandler must set the `upstream` param
getUpstream: (request) => getParam(request, 'upstream'),
},
preHandler: (request, _, done) => {
const name = getParam(request, 'name');

const upstream = DEV_MODE
? // Use port forwarding for local development:
// kubectl port-forward -n <namespace> svc/<service-name> <local.port>:<service.port>
`http://${process.env.MODEL_REGISTRY_SERVICE_HOST}:${process.env.MODEL_REGISTRY_SERVICE_PORT}`
: // Construct service URL
`http://${name}.${MODEL_REGISTRY_NAMESPACE}.svc.cluster.local:8080`;

// assign the `upstream` param so we can dynamically set the upstream URL for http-proxy
setParam(request, 'upstream', upstream);

fastify.log.info(`Proxy ${request.method} request ${request.url} to ${upstream}`);
done();
},
});
};
export default proxyService(
null,
{
port: 8080,
namespace: MODEL_REGISTRY_NAMESPACE,
},
{
// Use port forwarding for local development:
// kubectl port-forward -n odh-model-registries svc/<service-name> 8085:8080
host: process.env.MODEL_REGISTRY_SERVICE_HOST,
port: process.env.MODEL_REGISTRY_SERVICE_PORT,
},
null,
false,
);
91 changes: 50 additions & 41 deletions backend/src/utils/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ const notFoundError = (kind: string, name: string, e?: any, overrideMessage?: st
};

export const proxyService =
<K extends K8sResourceCommon>(
model: { apiGroup: string; apiVersion: string; plural: string; kind: string },
<K extends K8sResourceCommon = never>(
model: { apiGroup: string; apiVersion: string; plural: string; kind: string } | null,
service: {
port: number | string;
prefix?: string;
suffix?: string;
namespace?: string;
},
local: {
host: string;
Expand All @@ -44,7 +45,7 @@ export const proxyService =
async (fastify: KubeFastifyInstance): Promise<void> => {
fastify.register(httpProxy, {
upstream: '',
prefix: '/:namespace/:name',
prefix: service.namespace ? ':name' : '/:namespace/:name',
rewritePrefix: '',
replyOptions: {
// preHandler must set the `upstream` param
Expand All @@ -65,52 +66,60 @@ export const proxyService =
);
return;
}
const kc = fastify.kube.config;
const cluster = kc.getCurrentCluster();

// see `prefix` for named params
const namespace = getParam(request, 'namespace');
const namespace = service.namespace ?? getParam(request, 'namespace');
const name = getParam(request, 'name');

// retreive the gating resource by name and namespace
passThroughResource<K>(fastify, request, {
url: `${cluster.server}/apis/${model.apiGroup}/${model.apiVersion}/namespaces/${namespace}/${model.plural}/${name}`,
method: 'GET',
})
.then((resource) => {
return getDirectCallOptions(fastify, request, request.url).then((requestOptions) => {
if (isK8sStatus(resource)) {
done(notFoundError(model.kind, name));
} else if (!statusCheck || statusCheck(resource)) {
if (tls) {
const token = getAccessToken(requestOptions);
request.headers.authorization = `Bearer ${token}`;
}
const doServiceRequest = () => {
const scheme = tls ? 'https' : 'http';

const scheme = tls ? 'https' : 'http';
const upstream = DEV_MODE
? // Use port forwarding for local development:
// kubectl port-forward -n <namespace> svc/<service-name> <local.port>:<service.port>
`${scheme}://${local.host}:${local.port}`
: // Construct service URL
`${scheme}://${service.prefix || ''}${name}${
service.suffix ?? ''
}.${namespace}.svc.cluster.local:${service.port}`;

const upstream = DEV_MODE
? // Use port forwarding for local development:
// kubectl port-forward -n <namespace> svc/<service-name> <local.port>:<service.port>
`${scheme}://${local.host}:${local.port}`
: // Construct service URL
`${scheme}://${service?.prefix || ''}${resource.metadata.name}${
service?.suffix ?? ''
}.${resource.metadata.namespace}.svc.cluster.local:${service.port}`;
// assign the `upstream` param so we can dynamically set the upstream URL for http-proxy
setParam(request, 'upstream', upstream);

// assign the `upstream` param so we can dynamically set the upstream URL for http-proxy
setParam(request, 'upstream', upstream);
fastify.log.info(`Proxy ${request.method} request ${request.url} to ${upstream}`);
done();
};

fastify.log.info(`Proxy ${request.method} request ${request.url} to ${upstream}`);
done();
} else {
done(notFoundError(model.kind, name, undefined, 'service unavailable'));
}
});
if (model) {
const kc = fastify.kube.config;
const cluster = kc.getCurrentCluster();

// retreive the gating resource by name and namespace
passThroughResource<K>(fastify, request, {
url: `${cluster.server}/apis/${model.apiGroup}/${model.apiVersion}/namespaces/${namespace}/${model.plural}/${name}`,
method: 'GET',
})
.catch((e) => {
done(notFoundError(model.kind, name, e));
});
.then((resource) => {
return getDirectCallOptions(fastify, request, request.url).then((requestOptions) => {
if (isK8sStatus(resource)) {
done(notFoundError(model.kind, name));
} else if (!statusCheck || statusCheck(resource)) {
if (tls) {
const token = getAccessToken(requestOptions);
request.headers.authorization = `Bearer ${token}`;
}

doServiceRequest();
} else {
done(notFoundError(model.kind, name, undefined, 'service unavailable'));
}
});
})
.catch((e) => {
done(notFoundError(model.kind, name, e));
});
} else {
doServiceRequest();
}
},
});
};

0 comments on commit 13b5562

Please sign in to comment.