@crossplane-org/function-sdk-typescript 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +683 -0
- package/dist/example-function.d.ts +11 -0
- package/dist/example-function.d.ts.map +1 -0
- package/dist/example-function.js +93 -0
- package/dist/example-function.js.map +1 -0
- package/dist/function/function.d.ts +115 -0
- package/dist/function/function.d.ts.map +1 -0
- package/dist/function/function.js +111 -0
- package/dist/function/function.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +69 -0
- package/dist/main.js.map +1 -0
- package/dist/proto/google/protobuf/duration.d.ts +107 -0
- package/dist/proto/google/protobuf/duration.d.ts.map +1 -0
- package/dist/proto/google/protobuf/duration.js +90 -0
- package/dist/proto/google/protobuf/duration.js.map +1 -0
- package/dist/proto/google/protobuf/struct.d.ts +115 -0
- package/dist/proto/google/protobuf/struct.d.ts.map +1 -0
- package/dist/proto/google/protobuf/struct.js +452 -0
- package/dist/proto/google/protobuf/struct.js.map +1 -0
- package/dist/proto/run_function.d.ts +494 -0
- package/dist/proto/run_function.d.ts.map +1 -0
- package/dist/proto/run_function.js +2230 -0
- package/dist/proto/run_function.js.map +1 -0
- package/dist/request/request.d.ts +198 -0
- package/dist/request/request.d.ts.map +1 -0
- package/dist/request/request.js +219 -0
- package/dist/request/request.js.map +1 -0
- package/dist/resource/resource.d.ts +101 -0
- package/dist/resource/resource.d.ts.map +1 -0
- package/dist/resource/resource.js +98 -0
- package/dist/resource/resource.js.map +1 -0
- package/dist/response/response.d.ts +273 -0
- package/dist/response/response.d.ts.map +1 -0
- package/dist/response/response.js +339 -0
- package/dist/response/response.js.map +1 -0
- package/dist/runtime/runtime.d.ts +121 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +124 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +17 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Response utilities for working with RunFunctionResponse
|
|
3
|
+
*
|
|
4
|
+
* This module provides helper functions to build and manipulate RunFunctionResponse objects,
|
|
5
|
+
* including setting desired state, managing results, handling context, and working with
|
|
6
|
+
* composite resources and their status.
|
|
7
|
+
*/
|
|
8
|
+
import { Resource, RunFunctionRequest, RunFunctionResponse, Severity, Ready, } from "../proto/run_function.js";
|
|
9
|
+
import { Duration } from "../proto/google/protobuf/duration.js";
|
|
10
|
+
import { merge } from "ts-deepmerge";
|
|
11
|
+
/**
|
|
12
|
+
* Default time-to-live for function responses (60 seconds).
|
|
13
|
+
* Crossplane will call the function again when the TTL expires.
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_TTL = { seconds: 60, nanos: 0 };
|
|
16
|
+
export { DEFAULT_TTL };
|
|
17
|
+
/**
|
|
18
|
+
* Bootstrap a response from a request.
|
|
19
|
+
*
|
|
20
|
+
* This function creates a new RunFunctionResponse with the request's tag automatically
|
|
21
|
+
* copied, and initializes the desired state from the request. Using this function is
|
|
22
|
+
* the recommended pattern to ensure proper response initialization.
|
|
23
|
+
*
|
|
24
|
+
* The response will:
|
|
25
|
+
* - Copy the request's tag to the response metadata
|
|
26
|
+
* - Initialize the desired state from the request (or create empty if not present)
|
|
27
|
+
* - Set the TTL (time-to-live) for caching
|
|
28
|
+
* - Initialize empty results and conditions arrays
|
|
29
|
+
*
|
|
30
|
+
* @param req - The RunFunctionRequest to bootstrap from
|
|
31
|
+
* @param ttl - Optional time-to-live duration (defaults to 60 seconds)
|
|
32
|
+
* @returns A new RunFunctionResponse initialized from the request
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* async RunFunction(req: RunFunctionRequest): Promise<RunFunctionResponse> {
|
|
37
|
+
* let rsp = to(req);
|
|
38
|
+
* // Add your logic here
|
|
39
|
+
* normal(rsp, "Processing complete");
|
|
40
|
+
* return rsp;
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export function to(req, ttl) {
|
|
45
|
+
// Initialize desired state if needed
|
|
46
|
+
let desired = req.desired;
|
|
47
|
+
// If desired is not set, initialize it
|
|
48
|
+
if (!desired) {
|
|
49
|
+
desired = { composite: undefined, resources: {} };
|
|
50
|
+
}
|
|
51
|
+
// If composite is explicitly null, initialize it as an empty resource
|
|
52
|
+
if (desired.composite === null) {
|
|
53
|
+
desired.composite = Resource.fromJSON({});
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
conditions: [],
|
|
57
|
+
context: req.context,
|
|
58
|
+
desired: desired,
|
|
59
|
+
meta: { tag: req.meta?.tag || "", ttl: ttl || DEFAULT_TTL },
|
|
60
|
+
requirements: undefined,
|
|
61
|
+
results: [],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Update a map of desired composed resources by adding or updating a named resource.
|
|
66
|
+
*
|
|
67
|
+
* This is a helper function to add a single resource to a map of composed resources.
|
|
68
|
+
* It's useful when building up desired resources before calling setDesiredComposedResources.
|
|
69
|
+
*
|
|
70
|
+
* @param cds - The current map of composed resources
|
|
71
|
+
* @param res - The named resource to add or update
|
|
72
|
+
* @returns The updated map of composed resources
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* let dcds = getDesiredComposedResources(req);
|
|
77
|
+
* dcds = updateDesiredComposedResources(dcds, {
|
|
78
|
+
* name: "my-bucket",
|
|
79
|
+
* resource: Resource.fromJSON({ resource: bucketConfig })
|
|
80
|
+
* });
|
|
81
|
+
* rsp = setDesiredComposedResources(rsp, dcds);
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function updateDesiredComposedResources(cds, res) {
|
|
85
|
+
cds[res.name] = res.resource;
|
|
86
|
+
return cds;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Add a fatal result to the response.
|
|
90
|
+
*
|
|
91
|
+
* Fatal results cause the function pipeline run to be considered a failure.
|
|
92
|
+
* Subsequent functions may still run, but the first fatal result will be
|
|
93
|
+
* returned as an error. Fatal results should be used for errors that prevent
|
|
94
|
+
* the function from producing valid output.
|
|
95
|
+
*
|
|
96
|
+
* @param rsp - The RunFunctionResponse to add the result to
|
|
97
|
+
* @param message - The error message describing the fatal condition
|
|
98
|
+
* @returns The updated response
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* if (!requiredInput) {
|
|
103
|
+
* fatal(rsp, "Required input 'databaseSize' not provided");
|
|
104
|
+
* return rsp;
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export function fatal(rsp, message) {
|
|
109
|
+
if (rsp && rsp.results) {
|
|
110
|
+
rsp.results.push({
|
|
111
|
+
severity: Severity.SEVERITY_FATAL,
|
|
112
|
+
message: message,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return rsp;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Add a normal result to the response.
|
|
119
|
+
*
|
|
120
|
+
* Normal results are informational and emitted as normal events and debug logs
|
|
121
|
+
* associated with the composite resource (XR) or operation. They indicate
|
|
122
|
+
* successful processing or expected conditions.
|
|
123
|
+
*
|
|
124
|
+
* @param rsp - The RunFunctionResponse to add the result to
|
|
125
|
+
* @param message - The informational message
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* normal(rsp, "Successfully configured 3 database replicas");
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export function normal(rsp, message) {
|
|
133
|
+
if (rsp && rsp.results) {
|
|
134
|
+
rsp.results.push({
|
|
135
|
+
severity: Severity.SEVERITY_NORMAL,
|
|
136
|
+
message: message,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Add a warning result to the response.
|
|
142
|
+
*
|
|
143
|
+
* Warning results are non-fatal issues that should be brought to attention.
|
|
144
|
+
* The entire pipeline will run to completion, but warning events and debug logs
|
|
145
|
+
* will be emitted. Use warnings for recoverable issues or deprecated usage.
|
|
146
|
+
*
|
|
147
|
+
* @param rsp - The RunFunctionResponse to add the result to
|
|
148
|
+
* @param message - The warning message
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```typescript
|
|
152
|
+
* if (input.legacyFormat) {
|
|
153
|
+
* warning(rsp, "Using deprecated input format, please migrate to new format");
|
|
154
|
+
* }
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export function warning(rsp, message) {
|
|
158
|
+
if (rsp && rsp.results) {
|
|
159
|
+
rsp.results.push({
|
|
160
|
+
severity: Severity.SEVERITY_WARNING,
|
|
161
|
+
message: message,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Set the desired composed resources in the response.
|
|
167
|
+
*
|
|
168
|
+
* This function sets or merges the desired composed resources in the response.
|
|
169
|
+
* It uses deep merge to combine new resources with any existing resources,
|
|
170
|
+
* allowing functions to add or modify resources while preserving those set
|
|
171
|
+
* by previous functions in the pipeline.
|
|
172
|
+
*
|
|
173
|
+
* If the desired state or resources map don't exist, they will be initialized.
|
|
174
|
+
*
|
|
175
|
+
* @param rsp - The RunFunctionResponse to update
|
|
176
|
+
* @param dcds - A map of resource names to Resource objects to set as desired
|
|
177
|
+
* @returns The updated response
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* const dcds = getDesiredComposedResources(req);
|
|
182
|
+
* dcds["my-deployment"] = Resource.fromJSON({
|
|
183
|
+
* resource: { apiVersion: "apps/v1", kind: "Deployment", ... }
|
|
184
|
+
* });
|
|
185
|
+
* rsp = setDesiredComposedResources(rsp, dcds);
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
export function setDesiredComposedResources(rsp, dcds) {
|
|
189
|
+
// Ensure desired state exists
|
|
190
|
+
if (!rsp.desired) {
|
|
191
|
+
rsp.desired = { composite: undefined, resources: {} };
|
|
192
|
+
}
|
|
193
|
+
// Merge the new resources with existing ones
|
|
194
|
+
rsp.desired.resources = merge(rsp.desired.resources || {}, dcds);
|
|
195
|
+
return rsp;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Update a resource by merging source into target.
|
|
199
|
+
*
|
|
200
|
+
* This function performs a deep merge of the source resource into the target resource,
|
|
201
|
+
* allowing you to update specific fields while preserving others. The merge is performed
|
|
202
|
+
* using the ts-deepmerge library.
|
|
203
|
+
*
|
|
204
|
+
* @param src - The source Resource containing updates
|
|
205
|
+
* @param tgt - The target Resource to be updated
|
|
206
|
+
* @returns A new Resource with merged values
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```typescript
|
|
210
|
+
* const existing = getDesiredComposedResources(req)["my-resource"];
|
|
211
|
+
* const updated = update(
|
|
212
|
+
* Resource.fromJSON({ resource: { spec: { replicas: 5 } } }),
|
|
213
|
+
* existing
|
|
214
|
+
* );
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
export function update(src, tgt) {
|
|
218
|
+
return merge(tgt, src);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Set the desired composite resource status.
|
|
222
|
+
*
|
|
223
|
+
* This function updates only the status field of the desired composite resource.
|
|
224
|
+
* It merges the provided status with any existing status, allowing partial updates.
|
|
225
|
+
* Note that functions should only set the status of composite resources (XRs),
|
|
226
|
+
* not their metadata or spec.
|
|
227
|
+
*
|
|
228
|
+
* @param params - Object containing the response and status to set
|
|
229
|
+
* @param params.rsp - The RunFunctionResponse to update
|
|
230
|
+
* @param params.status - The status object to merge into the composite resource
|
|
231
|
+
* @returns The updated response
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* rsp = setDesiredCompositeStatus({
|
|
236
|
+
* rsp,
|
|
237
|
+
* status: {
|
|
238
|
+
* phase: "Ready",
|
|
239
|
+
* conditions: [{ type: "Synced", status: "True" }]
|
|
240
|
+
* }
|
|
241
|
+
* });
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
export function setDesiredCompositeStatus({ rsp, status }) {
|
|
245
|
+
if (rsp.desired?.composite?.resource) {
|
|
246
|
+
rsp.desired.composite.resource = merge(rsp.desired.composite.resource, {
|
|
247
|
+
"status": status,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
return rsp;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Set a context key in the response.
|
|
254
|
+
*
|
|
255
|
+
* Context allows functions to pass arbitrary data to subsequent functions in the
|
|
256
|
+
* pipeline. The context is initialized if it doesn't exist. Crossplane discards
|
|
257
|
+
* all context returned by the last function in the pipeline.
|
|
258
|
+
*
|
|
259
|
+
* @param rsp - The RunFunctionResponse to update
|
|
260
|
+
* @param key - The context key to set
|
|
261
|
+
* @param value - The value to associate with the key (can be any JSON-serializable value)
|
|
262
|
+
* @returns The updated response
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```typescript
|
|
266
|
+
* // Set context for next function in pipeline
|
|
267
|
+
* rsp = setContextKey(rsp, "database-endpoint", "db.example.com:5432");
|
|
268
|
+
* rsp = setContextKey(rsp, "connection-config", { host: "db.example.com", port: 5432 });
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
export function setContextKey(rsp, key, value) {
|
|
272
|
+
if (!rsp.context) {
|
|
273
|
+
rsp.context = {};
|
|
274
|
+
}
|
|
275
|
+
rsp.context[key] = value;
|
|
276
|
+
return rsp;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Set the desired composite resource in the response.
|
|
280
|
+
*
|
|
281
|
+
* This function sets the entire desired composite resource and optionally its ready status.
|
|
282
|
+
* The ready status can be used to override Crossplane's standard readiness detection,
|
|
283
|
+
* which normally determines the composite's ready state based on composed resources.
|
|
284
|
+
*
|
|
285
|
+
* Note: Ready status is only used for composition functions, not operations.
|
|
286
|
+
*
|
|
287
|
+
* @param rsp - The RunFunctionResponse to update
|
|
288
|
+
* @param resource - The desired composite resource to set
|
|
289
|
+
* @param ready - Optional ready status (READY_TRUE, READY_FALSE, or READY_UNSPECIFIED)
|
|
290
|
+
* @returns The updated response
|
|
291
|
+
*
|
|
292
|
+
* @example
|
|
293
|
+
* ```typescript
|
|
294
|
+
* const composite = getObservedCompositeResource(req);
|
|
295
|
+
* if (composite) {
|
|
296
|
+
* // Modify and set as desired with ready status
|
|
297
|
+
* rsp = setDesiredCompositeResource(rsp, composite, Ready.READY_TRUE);
|
|
298
|
+
* }
|
|
299
|
+
* ```
|
|
300
|
+
*/
|
|
301
|
+
export function setDesiredCompositeResource(rsp, resource, ready) {
|
|
302
|
+
if (!rsp.desired) {
|
|
303
|
+
rsp.desired = { composite: undefined, resources: {} };
|
|
304
|
+
}
|
|
305
|
+
// Create a new resource with the specified ready status using fromPartial
|
|
306
|
+
// to ensure proper type handling for the protobuf-generated Resource type
|
|
307
|
+
rsp.desired.composite = Resource.fromPartial({
|
|
308
|
+
resource: resource.resource,
|
|
309
|
+
connectionDetails: resource.connectionDetails,
|
|
310
|
+
ready: ready !== undefined ? ready : Ready.READY_UNSPECIFIED,
|
|
311
|
+
});
|
|
312
|
+
return rsp;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Set the function output in the response.
|
|
316
|
+
*
|
|
317
|
+
* Function output is specific to operation functions. The output must be a
|
|
318
|
+
* JSON-serializable object. Composite resources (XRs) will discard any function
|
|
319
|
+
* output, as it's only used by operations.
|
|
320
|
+
*
|
|
321
|
+
* @param rsp - The RunFunctionResponse to update
|
|
322
|
+
* @param output - The output object to set (must be JSON-serializable)
|
|
323
|
+
* @returns The updated response
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```typescript
|
|
327
|
+
* // For operation functions
|
|
328
|
+
* rsp = setOutput(rsp, {
|
|
329
|
+
* resourcesCreated: 5,
|
|
330
|
+
* status: "success",
|
|
331
|
+
* details: { timestamp: new Date().toISOString() }
|
|
332
|
+
* });
|
|
333
|
+
* ```
|
|
334
|
+
*/
|
|
335
|
+
export function setOutput(rsp, output) {
|
|
336
|
+
rsp.output = output;
|
|
337
|
+
return rsp;
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/response/response.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime utilities for creating and managing gRPC servers
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to create gRPC servers for Crossplane functions,
|
|
5
|
+
* handle TLS credentials, and manage server lifecycle. It simplifies the process
|
|
6
|
+
* of setting up a production-ready function server with proper security.
|
|
7
|
+
*/
|
|
8
|
+
import * as grpc from "@grpc/grpc-js";
|
|
9
|
+
import type { Logger } from "pino";
|
|
10
|
+
import { FunctionRunner } from "../function/function.js";
|
|
11
|
+
/**
|
|
12
|
+
* Configuration options for the gRPC server.
|
|
13
|
+
*/
|
|
14
|
+
export interface ServerOptions {
|
|
15
|
+
/**
|
|
16
|
+
* The address to listen on (e.g., "0.0.0.0:9443" or ":9443")
|
|
17
|
+
* Default is ":9443" when using the CLI
|
|
18
|
+
*/
|
|
19
|
+
address: string;
|
|
20
|
+
/**
|
|
21
|
+
* Whether to run without TLS encryption.
|
|
22
|
+
* Set to true for local development only. Production should use TLS.
|
|
23
|
+
* Default: false
|
|
24
|
+
*/
|
|
25
|
+
insecure?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Enable debug-level logging.
|
|
28
|
+
* Default: false
|
|
29
|
+
*/
|
|
30
|
+
debug?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Filesystem directory containing TLS certificates.
|
|
33
|
+
* Should contain: tls.key, tls.crt, and ca.crt
|
|
34
|
+
* Ignored if insecure is set to true.
|
|
35
|
+
*/
|
|
36
|
+
tlsServerCertsDir?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create gRPC ServerCredentials from TLS certificate files.
|
|
40
|
+
*
|
|
41
|
+
* This function loads TLS certificates from the filesystem and creates
|
|
42
|
+
* appropriate ServerCredentials for the gRPC server. In insecure mode,
|
|
43
|
+
* it returns insecure credentials (suitable for local development only).
|
|
44
|
+
*
|
|
45
|
+
* For secure mode, it expects three files in tlsServerCertsDir:
|
|
46
|
+
* - tls.key: The server's private key
|
|
47
|
+
* - tls.crt: The server's certificate
|
|
48
|
+
* - ca.crt: The certificate authority certificate
|
|
49
|
+
*
|
|
50
|
+
* @param opts - Server options containing TLS configuration
|
|
51
|
+
* @returns gRPC ServerCredentials (secure or insecure based on options)
|
|
52
|
+
* @throws Error if certificate files cannot be read in secure mode
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // Secure mode (production)
|
|
57
|
+
* const creds = getServerCredentials({
|
|
58
|
+
* address: ":9443",
|
|
59
|
+
* tlsServerCertsDir: "/tls"
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* // Insecure mode (development only)
|
|
63
|
+
* const creds = getServerCredentials({
|
|
64
|
+
* address: ":9443",
|
|
65
|
+
* insecure: true
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function getServerCredentials(opts?: ServerOptions): grpc.ServerCredentials;
|
|
70
|
+
/**
|
|
71
|
+
* Create a new gRPC server with the function runner registered.
|
|
72
|
+
*
|
|
73
|
+
* This function creates a gRPC server instance and registers the provided
|
|
74
|
+
* FunctionRunner to handle incoming RunFunction requests. The server is
|
|
75
|
+
* created but not yet bound to an address - use startServer to bind and start it.
|
|
76
|
+
*
|
|
77
|
+
* @param functionRunner - The FunctionRunner instance that will handle requests
|
|
78
|
+
* @param logger - Logger instance for debug and error logging
|
|
79
|
+
* @returns A configured gRPC Server instance ready to be started
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const runner = new FunctionRunner(new MyFunction(), logger);
|
|
84
|
+
* const server = newGrpcServer(runner, logger);
|
|
85
|
+
* startServer(server, { address: ":9443", insecure: false }, logger);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare function newGrpcServer(functionRunner: FunctionRunner, logger: Logger): grpc.Server;
|
|
89
|
+
/**
|
|
90
|
+
* Bind and start a gRPC server.
|
|
91
|
+
*
|
|
92
|
+
* This function binds the server to the specified address and starts listening
|
|
93
|
+
* for incoming connections. It handles both secure (TLS) and insecure modes
|
|
94
|
+
* based on the provided options. The binding happens asynchronously.
|
|
95
|
+
*
|
|
96
|
+
* The server will log when it successfully starts listening or if an error occurs
|
|
97
|
+
* during binding.
|
|
98
|
+
*
|
|
99
|
+
* @param server - The gRPC Server instance to start
|
|
100
|
+
* @param opts - Server options including address and TLS configuration
|
|
101
|
+
* @param logger - Logger instance for info and error logging
|
|
102
|
+
* @returns The same server instance (now bound and listening)
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const server = newGrpcServer(runner, logger);
|
|
107
|
+
* startServer(server, {
|
|
108
|
+
* address: "0.0.0.0:9443",
|
|
109
|
+
* tlsServerCertsDir: "/tls",
|
|
110
|
+
* debug: true
|
|
111
|
+
* }, logger);
|
|
112
|
+
*
|
|
113
|
+
* // For local development
|
|
114
|
+
* startServer(server, {
|
|
115
|
+
* address: "localhost:9443",
|
|
116
|
+
* insecure: true
|
|
117
|
+
* }, logger);
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare function startServer(server: grpc.Server, opts: ServerOptions, logger: Logger): grpc.Server;
|
|
121
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnC,OAAO,EAAE,cAAc,EAAa,MAAM,yBAAyB,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,oBAAoB,CAChC,IAAI,CAAC,EAAE,aAAa,GACrB,IAAI,CAAC,iBAAiB,CAkBxB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAMzF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAgBjG"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime utilities for creating and managing gRPC servers
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to create gRPC servers for Crossplane functions,
|
|
5
|
+
* handle TLS credentials, and manage server lifecycle. It simplifies the process
|
|
6
|
+
* of setting up a production-ready function server with proper security.
|
|
7
|
+
*/
|
|
8
|
+
import * as grpc from "@grpc/grpc-js";
|
|
9
|
+
import { readFileSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { FunctionRunner, getServer } from "../function/function.js";
|
|
12
|
+
/**
|
|
13
|
+
* Create gRPC ServerCredentials from TLS certificate files.
|
|
14
|
+
*
|
|
15
|
+
* This function loads TLS certificates from the filesystem and creates
|
|
16
|
+
* appropriate ServerCredentials for the gRPC server. In insecure mode,
|
|
17
|
+
* it returns insecure credentials (suitable for local development only).
|
|
18
|
+
*
|
|
19
|
+
* For secure mode, it expects three files in tlsServerCertsDir:
|
|
20
|
+
* - tls.key: The server's private key
|
|
21
|
+
* - tls.crt: The server's certificate
|
|
22
|
+
* - ca.crt: The certificate authority certificate
|
|
23
|
+
*
|
|
24
|
+
* @param opts - Server options containing TLS configuration
|
|
25
|
+
* @returns gRPC ServerCredentials (secure or insecure based on options)
|
|
26
|
+
* @throws Error if certificate files cannot be read in secure mode
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Secure mode (production)
|
|
31
|
+
* const creds = getServerCredentials({
|
|
32
|
+
* address: ":9443",
|
|
33
|
+
* tlsServerCertsDir: "/tls"
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Insecure mode (development only)
|
|
37
|
+
* const creds = getServerCredentials({
|
|
38
|
+
* address: ":9443",
|
|
39
|
+
* insecure: true
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function getServerCredentials(opts) {
|
|
44
|
+
if (opts?.insecure || opts?.tlsServerCertsDir === "" || opts?.tlsServerCertsDir === undefined) {
|
|
45
|
+
return grpc.ServerCredentials.createInsecure();
|
|
46
|
+
}
|
|
47
|
+
const tlsCertsDir = opts.tlsServerCertsDir;
|
|
48
|
+
if (typeof tlsCertsDir !== "string" || tlsCertsDir.trim() === "") {
|
|
49
|
+
throw new Error("tlsServerCertsDir must be a non-empty string when TLS is enabled");
|
|
50
|
+
}
|
|
51
|
+
const privateKey = readFileSync(join(tlsCertsDir, "tls.key"));
|
|
52
|
+
const certChain = readFileSync(join(tlsCertsDir, "tls.crt"));
|
|
53
|
+
const rootCerts = readFileSync(join(tlsCertsDir, "ca.crt"));
|
|
54
|
+
return grpc.ServerCredentials.createSsl(rootCerts, [{ private_key: privateKey, cert_chain: certChain }], false);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create a new gRPC server with the function runner registered.
|
|
58
|
+
*
|
|
59
|
+
* This function creates a gRPC server instance and registers the provided
|
|
60
|
+
* FunctionRunner to handle incoming RunFunction requests. The server is
|
|
61
|
+
* created but not yet bound to an address - use startServer to bind and start it.
|
|
62
|
+
*
|
|
63
|
+
* @param functionRunner - The FunctionRunner instance that will handle requests
|
|
64
|
+
* @param logger - Logger instance for debug and error logging
|
|
65
|
+
* @returns A configured gRPC Server instance ready to be started
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const runner = new FunctionRunner(new MyFunction(), logger);
|
|
70
|
+
* const server = newGrpcServer(runner, logger);
|
|
71
|
+
* startServer(server, { address: ":9443", insecure: false }, logger);
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export function newGrpcServer(functionRunner, logger) {
|
|
75
|
+
const server = getServer(functionRunner, logger);
|
|
76
|
+
if (logger) {
|
|
77
|
+
logger.debug("grpc server created");
|
|
78
|
+
}
|
|
79
|
+
return server;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Bind and start a gRPC server.
|
|
83
|
+
*
|
|
84
|
+
* This function binds the server to the specified address and starts listening
|
|
85
|
+
* for incoming connections. It handles both secure (TLS) and insecure modes
|
|
86
|
+
* based on the provided options. The binding happens asynchronously.
|
|
87
|
+
*
|
|
88
|
+
* The server will log when it successfully starts listening or if an error occurs
|
|
89
|
+
* during binding.
|
|
90
|
+
*
|
|
91
|
+
* @param server - The gRPC Server instance to start
|
|
92
|
+
* @param opts - Server options including address and TLS configuration
|
|
93
|
+
* @param logger - Logger instance for info and error logging
|
|
94
|
+
* @returns The same server instance (now bound and listening)
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const server = newGrpcServer(runner, logger);
|
|
99
|
+
* startServer(server, {
|
|
100
|
+
* address: "0.0.0.0:9443",
|
|
101
|
+
* tlsServerCertsDir: "/tls",
|
|
102
|
+
* debug: true
|
|
103
|
+
* }, logger);
|
|
104
|
+
*
|
|
105
|
+
* // For local development
|
|
106
|
+
* startServer(server, {
|
|
107
|
+
* address: "localhost:9443",
|
|
108
|
+
* insecure: true
|
|
109
|
+
* }, logger);
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export function startServer(server, opts, logger) {
|
|
113
|
+
const creds = getServerCredentials(opts);
|
|
114
|
+
logger.debug(`serverCredentials type: ${creds.constructor.name}`);
|
|
115
|
+
server.bindAsync(opts.address, creds, (err) => {
|
|
116
|
+
if (err) {
|
|
117
|
+
logger.error(`server bind error: ${err.message}`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
logger.info(`server started and listening on ${opts.address}`);
|
|
121
|
+
});
|
|
122
|
+
return server;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAiCpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,oBAAoB,CAChC,IAAoB;IAEpB,IAAI,IAAI,EAAE,QAAQ,IAAI,IAAI,EAAE,iBAAiB,KAAK,EAAE,IAAI,IAAI,EAAE,iBAAiB,KAAK,SAAS,EAAE,CAAC;QAC5F,OAAO,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,CAAC;IACnD,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,CAAC;IAC3C,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,iBAAiB,CAAC,SAAS,CACnC,SAAS,EACT,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EACpD,KAAK,CACR,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,aAAa,CAAC,cAA8B,EAAE,MAAc;IACxE,MAAM,MAAM,GAAG,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,WAAW,CAAC,MAAmB,EAAE,IAAmB,EAAE,MAAc;IAChF,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAElE,MAAM,CAAC,SAAS,CACZ,IAAI,CAAC,OAAO,EACZ,KAAK,EACL,CAAC,GAAG,EAAE,EAAE;QACJ,IAAI,GAAG,EAAE,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAClD,OAAO;QACX,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,mCAAmC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC,CACJ,CAAC;IACF,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["../src/vitest.config.ts"],"names":[],"mappings":";AAEA,wBAcG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
export default defineConfig({
|
|
3
|
+
test: {
|
|
4
|
+
globals: true,
|
|
5
|
+
environment: 'node',
|
|
6
|
+
coverage: {
|
|
7
|
+
provider: 'v8',
|
|
8
|
+
reporter: ['text', 'json', 'html'],
|
|
9
|
+
exclude: [
|
|
10
|
+
'node_modules/',
|
|
11
|
+
'dist/',
|
|
12
|
+
'src/proto/',
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=vitest.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitest.config.js","sourceRoot":"","sources":["../src/vitest.config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE;QACJ,OAAO,EAAE,IAAI;QACb,WAAW,EAAE,MAAM;QACnB,QAAQ,EAAE;YACR,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAClC,OAAO,EAAE;gBACP,eAAe;gBACf,OAAO;gBACP,YAAY;aACb;SACF;KACF;CACF,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@crossplane-org/function-sdk-typescript",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A Crossplane Function SDK for Typescript",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"crossplane",
|
|
7
|
+
"kubernetes",
|
|
8
|
+
"typescript"
|
|
9
|
+
],
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "github.com/upbound/function-sdk-typescript"
|
|
13
|
+
},
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"author": "Steven Borrelli",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "dist/index.js",
|
|
18
|
+
"types": "dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"clean": "scripts/clean.sh",
|
|
31
|
+
"build": "npx tsc",
|
|
32
|
+
"pack": "npm pack",
|
|
33
|
+
"prepublishOnly": "npm run build",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"test:watch": "vitest",
|
|
36
|
+
"test:coverage": "vitest run --coverage"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@grpc/grpc-js": "^1.12.4",
|
|
40
|
+
"@grpc/proto-loader": "^0.8.0",
|
|
41
|
+
"google-protobuf": "^4.0.0",
|
|
42
|
+
"kubernetes-models": "^4.5.1",
|
|
43
|
+
"pino": "^10.1.0",
|
|
44
|
+
"ts-deepmerge": "^7.0.3",
|
|
45
|
+
"ts-proto": "^2.8.3"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/google-protobuf": "^3.15.12",
|
|
49
|
+
"@types/node": "^22.10.5",
|
|
50
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
51
|
+
"ts-node": "^10.9.2",
|
|
52
|
+
"typescript": "^5.7.2",
|
|
53
|
+
"vitest": "^2.1.8"
|
|
54
|
+
}
|
|
55
|
+
}
|