lade_sdk/providers/network/
mod.rs1use anyhow::{Result, bail};
2use rustc_hash::FxHashMap;
3use std::collections::HashMap;
4
5mod kubectl;
6mod kubefwd;
7mod ssh;
8mod tsh;
9
10#[derive(Debug, Clone)]
11pub enum ProviderSpec {
12 Kubectl {
13 cluster_endpoint: String,
14 context_selector: String,
15 namespace: String,
16 kind: String,
17 name: String,
18 remote_port: String,
19 pod_running_timeout: Option<String>,
20 },
21 Kubefwd {
22 cluster_endpoint: String,
23 context_selector: String,
24 namespace: String,
25 kind: String,
26 name: String,
27 service_port: u16,
28 domain: Option<String>,
29 selector: Option<String>,
30 },
31 TshKubeCluster {
32 teleport_proxy: String,
33 kube_cluster: String,
34 namespace: String,
35 kind: String,
36 name: String,
37 remote_port: u16,
38 },
39 TshApp {
40 teleport_proxy: String,
41 app_name: String,
42 target_port: Option<u16>,
43 },
44 Ssh {
45 jump_host: String,
46 jump_port: u16,
47 remote_host: String,
48 remote_port: u16,
49 },
50}
51
52pub trait NetworkProvider: Sync {
53 fn scheme(&self) -> &'static str;
54 fn parse(
55 &self,
56 authority: &str,
57 segments: &[&str],
58 query: &HashMap<String, String>,
59 ) -> Result<ProviderSpec>;
60}
61
62pub struct NetworkProviders {
63 by_scheme: FxHashMap<&'static str, Box<dyn NetworkProvider + Send>>,
64}
65
66impl Default for NetworkProviders {
67 fn default() -> Self {
68 Self::new()
69 }
70}
71
72impl NetworkProviders {
73 pub fn new() -> Self {
74 let providers: Vec<Box<dyn NetworkProvider + Send>> = vec![
75 Box::new(kubectl::KubectlProvider),
76 Box::new(kubefwd::KubefwdProvider),
77 Box::new(tsh::TshProvider),
78 Box::new(ssh::SshProvider),
79 ];
80 let by_scheme = providers
81 .into_iter()
82 .map(|provider| (provider.scheme(), provider))
83 .collect();
84 Self { by_scheme }
85 }
86
87 pub fn provider(&self, scheme: &str) -> Option<&(dyn NetworkProvider + Send)> {
88 self.by_scheme.get(scheme).map(|p| p.as_ref())
89 }
90}
91
92pub(crate) fn reject_unknown_query(
93 query: &HashMap<String, String>,
94 allowed: &[&str],
95) -> Result<()> {
96 for key in query.keys() {
97 if !allowed.contains(&key.as_str()) {
98 bail!("unsupported query parameter '{}'", key);
99 }
100 }
101 Ok(())
102}