diff --git a/src/example-function.ts b/src/example-function.ts deleted file mode 100644 index a2495b1..0000000 --- a/src/example-function.ts +++ /dev/null @@ -1,113 +0,0 @@ -// Example function implementation demonstrating how to use the SDK -import { Resource, RunFunctionRequest, RunFunctionResponse } from './proto/run_function.js'; -import type { Logger } from 'pino'; -import { Pod } from 'kubernetes-models/v1'; -import { fatal, normal, setDesiredComposedResources, to } from './response/response.js'; -import { - getDesiredComposedResources, - getDesiredCompositeResource, - getObservedCompositeResource, -} from './request/request.js'; -import type { FunctionHandler } from './function/function.js'; - -/** - * ExampleFunction is a sample implementation showing how to use the SDK - * This creates a Deployment and Pod as example resources - */ -export class ExampleFunction implements FunctionHandler { - RunFunction(req: RunFunctionRequest, logger?: Logger): Promise { - const startTime = Date.now(); - - // Set up a minimal response from the request - let rsp = to(req); - - try { - // Get our Observed Composite - const oxr = getObservedCompositeResource(req); - logger?.debug({ oxr }, 'Observed composite resource'); - - // Get our Desired Composite - const dxr = getDesiredCompositeResource(req); - logger?.debug({ dxr }, 'Desired composite resource'); - - // List the Desired Composed resources - const dcds = getDesiredComposedResources(req); - - // Create resource from a JSON object - dcds['deployment'] = Resource.fromJSON({ - resource: { - apiVersion: 'apps/v1', - kind: 'Deployment', - metadata: { - name: 'my-deployment', - namespace: 'foo', - }, - spec: { - replicas: 3, - selector: { - matchLabels: { - app: 'my-app', - }, - }, - template: { - metadata: { - labels: { - app: 'my-app', - }, - }, - spec: { - containers: [ - { - name: 'my-container', - image: 'my-image:latest', - ports: [ - { - containerPort: 80, - }, - ], - }, - ], - }, - }, - }, - }, - }); - - // Create a resource from a Model at https://github.com/tommy351/kubernetes-models-ts - const pod = new Pod({ - metadata: { - name: 'pod', - namespace: 'default', - }, - spec: { - containers: [], - }, - }); - - pod.validate(); - - dcds['pod'] = Resource.fromJSON({ resource: pod.toJSON() }); - - // Merge dcds with existing resources using the response helper - rsp = setDesiredComposedResources(rsp, dcds); - - const duration = Date.now() - startTime; - logger?.info({ duration: `${duration}ms` }, 'Function completed successfully'); - - normal(rsp, 'processing complete'); - return Promise.resolve(rsp); - } catch (error) { - const duration = Date.now() - startTime; - logger?.error( - { - error: error instanceof Error ? error.message : String(error), - duration: `${duration}ms`, - }, - 'Function invocation failed' - ); - - fatal(rsp, error instanceof Error ? error.message : String(error)); - return Promise.resolve(rsp); - } - } -} diff --git a/src/main.ts b/src/main.ts deleted file mode 100644 index 0a5f697..0000000 --- a/src/main.ts +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env node - -import { Command } from 'commander'; -import { newGrpcServer, startServer } from './runtime/runtime.js'; -import type { ServerOptions } from './runtime/runtime.js'; -import { pino } from 'pino'; -import { FunctionRunner } from './function/function.js'; -import { ExampleFunction } from './example-function.js'; - -// Type for commander options -type OptionValues = Record; - -// defaultAddress where the function will listen for gRPC connections -const defaultAddress = '0.0.0.0:9443'; -// defaultTlsServerCertsDir is the directory where the XP package reconciler stores generated TLS certs -const defaultTlsServerCertsDir = '/tls/server'; - -const _logger = pino({ - level: 'info', -}); - -const program = new Command('function-typescript-example') - .option('--address', 'Address at which to listen for gRPC connections', defaultAddress) - .option('-d, --debug', 'Emit debug logs.', false) - .option('--insecure', 'Run without mTLS credentials.', false) - .option( - '--tls-server-certs-dir [Directory]', - 'Serve using mTLS certificates in this directory. The directory should contain tls.key, tls.crt, and ca.crt files.', - defaultTlsServerCertsDir - ); - -program.parse(process.argv); - -function parseArgs(args: OptionValues): ServerOptions { - return { - address: args?.address || defaultAddress, - debug: args.debug, - insecure: args.insecure, - tlsServerCertsDir: args.tlsServerCertsDir, - }; -} - -function main() { - const args = program.opts(); - const opts = parseArgs(args); - - const logger = pino({ - level: opts?.debug ? 'debug' : 'info', - formatters: { - level: (label) => { - return { severity: label.toUpperCase() }; - }, - }, - }); - logger.debug({ 'options passed to function': opts }); - try { - // Create an instance of your function implementation - // This is an example - users would replace ExampleFunction with their own implementation - const exampleFunction = new ExampleFunction(); - - // Create the function runner with your handler - const fnRunner = new FunctionRunner(exampleFunction, logger); - - // Create and start the gRPC server - const server = newGrpcServer(fnRunner, logger); - startServer(server, opts, logger); - - // Keep the process running to handle gRPC requests - process.on('SIGINT', () => { - logger.info('shutting down gracefully...'); - server.tryShutdown((err) => { - if (err) { - logger.error(err, 'error during shutdown'); - process.exit(1); - } - logger.info('server shut down successfully'); - process.exit(0); - }); - }); - } catch (err) { - logger.error(err); - - process.exit(-1); - } -} - -main();