Skip to content

Commit 55ccce2

Browse files
authored
Introduce an API to establish channels (#16)
* Introduce an API to establish channels * Rename expectChannel to expectTunnel I think I'm using the word 'channel' for the individual streams within a connection, and the word 'tunnel' for the overall bundle of streams that are going over a given TCP socket. * Rename ChannelTunnel to KubernetesTunnel * Streams don't need 'close', they have a writable. * Let's add tunnel protocols to types I guess
1 parent 9b39390 commit 55ccce2

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

lib/contract.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,39 @@ export interface RequestOptions {
2121
bodyStream?: ReadableStream<Uint8Array>;
2222

2323
accept?: string;
24+
expectTunnel?: string[];
2425
expectStream?: boolean;
2526
expectJson?: boolean;
2627
}
2728

29+
export interface KubernetesTunnel<Tproto extends string> {
30+
/** Indicates which network protocol is in use.
31+
* This changes semantics, largely due to Kubernetes tunnel API quirks. */
32+
readonly transportProtocol: 'SPDY' | 'WebSocket' | 'Opaque';
33+
readonly subProtocol: Tproto;
34+
/** Set up a channel, using either SPDY or Websocket semantics. */
35+
getChannel<
36+
Treadable extends boolean,
37+
Twritable extends boolean,
38+
>(opts: {
39+
// Different transports identify streams different ways
40+
spdyHeaders?: Record<string,string | number>;
41+
streamIndex?: number;
42+
// What streams should be hooked up
43+
readable: Treadable;
44+
writable: Twritable;
45+
}): Promise<{
46+
readable: Treadable extends true ? ReadableStream<Uint8Array> : null;
47+
writable: Twritable extends true ? WritableStream<Uint8Array> : null;
48+
}>;
49+
/** Call once after creating the initial channels. */
50+
ready(): Promise<void>;
51+
/** Disconnects the underlying transport. */
52+
stop(): Promise<void>;
53+
}
54+
2855
export interface RestClient {
56+
performRequest<Tproto extends string>(opts: RequestOptions & {expectTunnel: Tproto[]}): Promise<KubernetesTunnel<Tproto>>;
2957
performRequest(opts: RequestOptions & {expectStream: true; expectJson: true}): Promise<ReadableStream<JSONValue>>;
3058
performRequest(opts: RequestOptions & {expectStream: true}): Promise<ReadableStream<Uint8Array>>;
3159
performRequest(opts: RequestOptions & {expectJson: true}): Promise<JSONValue>;

transports/via-kubeconfig.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ export class KubeConfigRestClient implements RestClient {
103103
console.error(opts.method, path);
104104
}
105105

106+
if (opts.expectTunnel) throw new Error(
107+
`Channel-based APIs are not currently implemented by this client.`);
108+
106109
const headers: Record<string, string> = {};
107110

108111
if (!this.ctx.cluster.server) throw new Error(`No server URL found in KubeConfig`);

transports/via-kubectl-raw.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ export class KubectlRawRestClient implements RestClient {
108108
const hasReqBody = opts.bodyJson !== undefined || !!opts.bodyRaw || !!opts.bodyStream;
109109
isVerbose && console.error(opts.method, path, hasReqBody ? '(w/ body)' : '');
110110

111+
if (opts.expectTunnel) throw new Error(
112+
`Channel-based APIs are not currently implemented by this client.`);
113+
111114
let rawArgs = [command, ...(hasReqBody ? ['-f', '-'] : []), "--raw", path];
112115

113116
if (command === 'patch') {

0 commit comments

Comments
 (0)