From 1596ffa23b53ee475cd567a8b0248e6195edf2bb Mon Sep 17 00:00:00 2001 From: Daniel Lamando Date: Tue, 10 Sep 2024 13:41:36 +0200 Subject: [PATCH] Green the CI, Require Deno v1.41+ (#22) * Ignore type error around TLS client certs * Not like that * Add deno v1.45 to CI * Update for Deno 2 removals * Update how mTls is provided for Deno 1.41+ --- .github/workflows/deno-ci.yaml | 36 +++-------------------------- README.md | 2 +- lib/kubeconfig.ts | 12 +++++----- transports/via-kubeconfig.ts | 5 ++-- tunnel-beta/examples/ws-exec-poc.ts | 2 +- tunnel-beta/via-spdy-transport.ts | 5 ++-- tunnel-beta/via-websocket.ts | 3 +++ 7 files changed, 20 insertions(+), 45 deletions(-) diff --git a/.github/workflows/deno-ci.yaml b/.github/workflows/deno-ci.yaml index 29502d6..b2ca5ae 100644 --- a/.github/workflows/deno-ci.yaml +++ b/.github/workflows/deno-ci.yaml @@ -13,11 +13,9 @@ jobs: strategy: matrix: deno-version: - - v1.28 - - v1.30 - - v1.32 - - v1.35 - - v1.39 + - v1.41 + - v1.43 + - v1.45 - canary fail-fast: false # run each branch to completion @@ -45,33 +43,5 @@ jobs: - name: Check demo.ts run: time deno check --unstable demo.ts - check-unstable: - runs-on: ubuntu-latest - name: Check Unstable w/ ${{ matrix.deno-version }} - strategy: - matrix: - deno-version: - - v1.39 - - canary - fail-fast: false # run each branch to completion - - steps: - - name: Checkout source - uses: actions/checkout@v4 - - - name: Use Deno ${{ matrix.deno-version }} - uses: denoland/setup-deno@v1 - with: - deno-version: ${{ matrix.deno-version }} - - # "https" cache: code from the Internet - # External sources won't change much so we use less precise keys - - name: Cache https:// - uses: actions/cache@v4 - with: - path: ~/.cache/deno/deps/https - key: deno-https/v1-${{ github.sha }} - restore-keys: deno-https/v1- - - name: Check tunnel-beta/examples/ws-exec-poc.ts run: time deno check --unstable tunnel-beta/examples/ws-exec-poc.ts diff --git a/README.md b/README.md index 1f8dd74..95d08f7 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,6 @@ Check out `lib/contract.ts` to see the type/API contract. ## Changelog - * `v0.7.0` on `2023-08-13`: Port `KubectlRawRestClient` over to newer `Deno.Command()` API. Support patching subresources & opening PodExec tunnels in `KubectlRawRestClient`. @@ -61,6 +60,7 @@ Check out `lib/contract.ts` to see the type/API contract. * `v0.7.1` on `2023-09-24`: Update std dependencies to `/std@0.202.0` * `v0.7.2` on `2023-12-29`: Fix `WebsocketTunnel` for Deno v1.38 change + * `v0.7.3` on `2024-09-10`: Drop support for Deno v1.40 and earlier. * `v0.6.0` on `2023-08-08`: Introduce an API for opening Kubernetes tunnels, useful for `PodExec` and others. diff --git a/lib/kubeconfig.ts b/lib/kubeconfig.ts index 1cdd82b..a907528 100644 --- a/lib/kubeconfig.ts +++ b/lib/kubeconfig.ts @@ -28,8 +28,8 @@ export class KubeConfig { const defaultPath = joinPath(Deno.env.get("HOME") || Deno.env.get("USERPROFILE") || "/root", ".kube", "config"); try { return await KubeConfig.readFromPath(defaultPath); - } catch (err) { - if (err.name === 'NotFound') { + } catch (err: unknown) { + if ((err as Error).name === 'NotFound') { return new KubeConfig(mergeKubeConfigs([])); } throw err; @@ -193,12 +193,12 @@ export class KubeConfigContext { if (expiresAt.valueOf() > Date.now()) { return `Bearer ${config['access-token']}`; } else throw new Error( - `TODO: GCP auth-provider token expired, use a kubectl command to refresh for now`); + `GCP "auth-provider" token expired, run a kubectl command to refresh. Or consider updating to "exec"`); } else throw new Error( - `TODO: GCP auth-provider lacks a cached token, use a kubectl command to refresh for now`); + `GCP "auth-provider" lacks a cached token, run a kubectl command to refresh. Or consider updating to "exec"`); default: throw new Error( - `TODO: this kubeconfig's auth-provider (${name}) isn't supported yet`); + `This kubeconfig's "auth-provider" (${name}) isn't supported. Consider updating to "exec"`); } } else if (this.user['exec']) { @@ -221,7 +221,7 @@ export class KubeConfigContext { const execConfig = this.user['exec']; if (!execConfig) throw new Error(`BUG: execConfig disappeared`); - const isTTY = Deno.isatty(Deno.stdin.rid); + const isTTY = Deno.stdin.isTerminal(); const stdinPolicy = execConfig.interactiveMode ?? 'IfAvailable'; if (stdinPolicy == 'Always' && !isTTY) { throw new Error(`KubeConfig exec plugin wants a TTY, but stdin is not a TTY`); diff --git a/transports/via-kubeconfig.ts b/transports/via-kubeconfig.ts index 18d63c6..45f37db 100644 --- a/transports/via-kubeconfig.ts +++ b/transports/via-kubeconfig.ts @@ -80,8 +80,9 @@ export class KubeConfigRestClient implements RestClient { if (Deno.createHttpClient) { httpClient = Deno.createHttpClient({ caCerts: serverTls ? [serverTls.serverCert] : [], - certChain: tlsAuth?.userCert, - privateKey: tlsAuth?.userKey, + //@ts-ignore-error deno unstable API. Not typed? + cert: tlsAuth?.userCert, + key: tlsAuth?.userKey, }); } else if (tlsAuth) { console.error('WARN: cannot use certificate-based auth without --unstable'); diff --git a/tunnel-beta/examples/ws-exec-poc.ts b/tunnel-beta/examples/ws-exec-poc.ts index 4f0c99b..4f0b802 100755 --- a/tunnel-beta/examples/ws-exec-poc.ts +++ b/tunnel-beta/examples/ws-exec-poc.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env -S deno run --unstable --allow-env --allow-read --allow-net +#!/usr/bin/env -S deno run --unstable-net --allow-env --allow-read --allow-net --cert=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt import { WebsocketRestClient } from "../via-websocket.ts"; diff --git a/tunnel-beta/via-spdy-transport.ts b/tunnel-beta/via-spdy-transport.ts index a445e67..0cd5892 100644 --- a/tunnel-beta/via-spdy-transport.ts +++ b/tunnel-beta/via-spdy-transport.ts @@ -21,8 +21,9 @@ export class SpdyEnabledRestClient extends KubeConfigRestClient { port: url.port ? parseInt(url.port) : 443, alpnProtocols: ['http/1.1'], caCerts: serverTls?.serverCert ? [serverTls.serverCert] : [], - certChain: clientTls?.userCert, - privateKey: clientTls?.userKey, + //@ts-ignore-error deno unstable API. Not typed? + cert: clientTls?.userCert, + key: clientTls?.userKey, }); const transport = await dialSpdyTunnel({ diff --git a/tunnel-beta/via-websocket.ts b/tunnel-beta/via-websocket.ts index cd5c326..bbcec9b 100644 --- a/tunnel-beta/via-websocket.ts +++ b/tunnel-beta/via-websocket.ts @@ -9,6 +9,8 @@ import { KubeConfigRestClient } from "../transports/via-kubeconfig.ts"; * WebSockets have various limits within the Kubernetes and Deno ecosystem, * but they work quite well in several situations and have good backpressure support. * + * * Run Deno with `--unstable-net` to enable the required WebSocketStream API. + * * * For most clusters, you'll need to have Deno trust the cluster CA. * Otherwise you'll get an `UnknownIssuer` error. * In-cluster, you just need to pass `--cert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt` @@ -22,6 +24,7 @@ import { KubeConfigRestClient } from "../transports/via-kubeconfig.ts"; * (TODO: find or create Kubernetes ticket to track this) * * * stdin restricted for exec/attach due to lack of EOF signal. + * Addressed in Kubernetes v1.29 via new `v5.channel.k8s.io` protocol. * Upstream work: https://github.com/kubernetes/kubernetes/pull/119157 */ export class WebsocketRestClient extends KubeConfigRestClient {