Skip to main content

kube_portforward/
lib.rs

1//! Kubernetes port-forward over SPDY
2//!
3//! Speaks `SPDY/3.1+portforward.k8s.io` (tunnelled inside WebSocket
4//! binary messages) by default, falling back to the legacy `Upgrade:
5//! SPDY/3.1` path when the apiserver rejects the WebSocket subprotocol.
6//! Multiplexes many concurrent local TCP connections over a small pool of
7//! upgraded connections using the SPDY/3.1 frame format.
8//!
9//! ## Why not `kube::Api::portforward`?
10//!
11//! `kube::Api::portforward` opens a new WebSocket upgrade for every stream
12//! pair, has no keepalive, and gives you opaque errors. This crate
13//! multiplexes many stream pairs per upgrade, runs a Ping/Pong watchdog,
14//! exposes structured `thiserror` errors, and gracefully falls back to the
15//! legacy SPDY/3.1 path when the apiserver is too old for KEP-4006.
16//!
17//! ## Quick Start
18//!
19//! ```no_run
20//! use kube_portforward::Client;
21//! use tokio::io::AsyncWriteExt;
22//!
23//! # async fn run(kube: kube::Client, url: http::Uri) -> Result<(), Box<dyn std::error::Error>> {
24//! let client = Client::new(kube, url);
25//! let session = client.session("default", "nginx", 80).open().await?;
26//! let mut stream = session.connect().await?;
27//! stream.write_all(b"GET / HTTP/1.0\r\n\r\n").await?;
28//! session.close().await?;
29//! # Ok(()) }
30//! ```
31
32pub(crate) mod client;
33pub(crate) mod connect;
34pub(crate) mod error;
35pub(crate) mod forwarder;
36pub(crate) mod pod_watch;
37pub(crate) mod recovery;
38pub(crate) mod session;
39pub(crate) mod stream;
40pub(crate) mod subprotocol;
41
42pub use client::{
43    Client,
44    ClientBuilder,
45    SessionBuilder,
46};
47pub use error::Error;
48pub use forwarder::{
49    Forwarder,
50    ForwarderBuilder,
51};
52pub use pod_watch::{
53    PodChange,
54    PodSelector,
55    PodWatcher,
56    ReadyPod,
57};
58pub use recovery::{
59    RecoveryCallback,
60    RecoverySignal,
61};
62pub use session::Session;
63pub use stream::{
64    DataStream,
65    ErrorStream,
66    Stream,
67};
68pub use subprotocol::Subprotocol;