mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
feat: kube protocol support (#267)
This commit is contained in:
committed by
GitHub
parent
cf529c1678
commit
f757336d75
@@ -2,6 +2,10 @@
|
||||
//!
|
||||
//! `bookmarks` is the module which provides data types and de/serializer for bookmarks
|
||||
|
||||
mod aws_s3;
|
||||
mod kube;
|
||||
mod smb;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
@@ -9,9 +13,12 @@ use std::str::FromStr;
|
||||
use serde::de::Error as DeError;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
pub use self::aws_s3::S3Params;
|
||||
pub use self::kube::KubeParams;
|
||||
pub use self::smb::SmbParams;
|
||||
use crate::filetransfer::params::{
|
||||
AwsS3Params, GenericProtocolParams, ProtocolParams, SmbParams as TransferSmbParams,
|
||||
WebDAVProtocolParams,
|
||||
AwsS3Params, GenericProtocolParams, KubeProtocolParams, ProtocolParams,
|
||||
SmbParams as TransferSmbParams, WebDAVProtocolParams,
|
||||
};
|
||||
use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
|
||||
|
||||
@@ -44,32 +51,14 @@ pub struct Bookmark {
|
||||
pub remote_path: Option<PathBuf>,
|
||||
/// local folder to open at startup
|
||||
pub local_path: Option<PathBuf>,
|
||||
/// Kube params; optional. When used other fields are empty for sure
|
||||
pub kube: Option<KubeParams>,
|
||||
/// S3 params; optional. When used other fields are empty for sure
|
||||
pub s3: Option<S3Params>,
|
||||
/// SMB params; optional. Extra params required for SMB protocol
|
||||
pub smb: Option<SmbParams>,
|
||||
}
|
||||
|
||||
/// Connection parameters for Aws s3 protocol
|
||||
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Default)]
|
||||
pub struct S3Params {
|
||||
pub bucket: String,
|
||||
pub region: Option<String>,
|
||||
pub endpoint: Option<String>,
|
||||
pub profile: Option<String>,
|
||||
pub access_key: Option<String>,
|
||||
pub secret_access_key: Option<String>,
|
||||
/// NOTE: there are no session token and security token since they are always temporary
|
||||
pub new_path_style: Option<bool>,
|
||||
}
|
||||
|
||||
/// Extra Connection parameters for SMB protocol
|
||||
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Default)]
|
||||
pub struct SmbParams {
|
||||
pub share: String,
|
||||
pub workgroup: Option<String>,
|
||||
}
|
||||
|
||||
// -- impls
|
||||
|
||||
impl From<FileTransferParams> for Bookmark {
|
||||
@@ -87,6 +76,7 @@ impl From<FileTransferParams> for Bookmark {
|
||||
password: params.password,
|
||||
remote_path,
|
||||
local_path,
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
},
|
||||
@@ -98,9 +88,22 @@ impl From<FileTransferParams> for Bookmark {
|
||||
password: None,
|
||||
remote_path,
|
||||
local_path,
|
||||
kube: None,
|
||||
s3: Some(S3Params::from(params)),
|
||||
smb: None,
|
||||
},
|
||||
ProtocolParams::Kube(params) => Self {
|
||||
protocol,
|
||||
address: None,
|
||||
port: None,
|
||||
username: None,
|
||||
password: None,
|
||||
remote_path,
|
||||
local_path,
|
||||
kube: Some(KubeParams::from(params)),
|
||||
s3: None,
|
||||
smb: None,
|
||||
},
|
||||
ProtocolParams::Smb(params) => Self {
|
||||
smb: Some(SmbParams::from(params.clone())),
|
||||
protocol,
|
||||
@@ -113,6 +116,7 @@ impl From<FileTransferParams> for Bookmark {
|
||||
password: params.password,
|
||||
remote_path,
|
||||
local_path,
|
||||
kube: None,
|
||||
s3: None,
|
||||
},
|
||||
ProtocolParams::WebDAV(parms) => Self {
|
||||
@@ -123,6 +127,7 @@ impl From<FileTransferParams> for Bookmark {
|
||||
password: Some(parms.password),
|
||||
remote_path,
|
||||
local_path,
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
},
|
||||
@@ -149,6 +154,11 @@ impl From<Bookmark> for FileTransferParams {
|
||||
.password(bookmark.password);
|
||||
Self::new(bookmark.protocol, ProtocolParams::Generic(params))
|
||||
}
|
||||
FileTransferProtocol::Kube => {
|
||||
let params = bookmark.kube.unwrap_or_default();
|
||||
let params = KubeProtocolParams::from(params);
|
||||
Self::new(bookmark.protocol, ProtocolParams::Kube(params))
|
||||
}
|
||||
#[cfg(unix)]
|
||||
FileTransferProtocol::Smb => {
|
||||
let params = TransferSmbParams::new(
|
||||
@@ -187,50 +197,6 @@ impl From<Bookmark> for FileTransferParams {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AwsS3Params> for S3Params {
|
||||
fn from(params: AwsS3Params) -> Self {
|
||||
S3Params {
|
||||
bucket: params.bucket_name,
|
||||
region: params.region,
|
||||
endpoint: params.endpoint,
|
||||
profile: params.profile,
|
||||
access_key: params.access_key,
|
||||
secret_access_key: params.secret_access_key,
|
||||
new_path_style: Some(params.new_path_style),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<S3Params> for AwsS3Params {
|
||||
fn from(params: S3Params) -> Self {
|
||||
AwsS3Params::new(params.bucket, params.region, params.profile)
|
||||
.endpoint(params.endpoint)
|
||||
.access_key(params.access_key)
|
||||
.secret_access_key(params.secret_access_key)
|
||||
.new_path_style(params.new_path_style.unwrap_or(false))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl From<TransferSmbParams> for SmbParams {
|
||||
fn from(params: TransferSmbParams) -> Self {
|
||||
Self {
|
||||
share: params.share,
|
||||
workgroup: params.workgroup,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl From<TransferSmbParams> for SmbParams {
|
||||
fn from(params: TransferSmbParams) -> Self {
|
||||
Self {
|
||||
share: params.share,
|
||||
workgroup: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_protocol<'de, D>(deserializer: D) -> Result<FileTransferProtocol, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
@@ -276,6 +242,7 @@ mod tests {
|
||||
password: Some(String::from("password")),
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
};
|
||||
@@ -287,6 +254,7 @@ mod tests {
|
||||
password: Some(String::from("password")),
|
||||
remote_path: Some(PathBuf::from("/home")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
};
|
||||
@@ -380,6 +348,38 @@ mod tests {
|
||||
assert_eq!(s3.secret_access_key.as_deref().unwrap(), "pluto");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bookmark_from_kube_ftparams() {
|
||||
let params = ProtocolParams::Kube(KubeProtocolParams {
|
||||
pod: "pod".to_string(),
|
||||
container: "container".to_string(),
|
||||
namespace: Some("default".to_string()),
|
||||
username: Some("root".to_string()),
|
||||
cluster_url: Some("https://localhost:6443".to_string()),
|
||||
client_cert: Some("cert".to_string()),
|
||||
client_key: Some("key".to_string()),
|
||||
});
|
||||
let params: FileTransferParams =
|
||||
FileTransferParams::new(FileTransferProtocol::Kube, params);
|
||||
let bookmark = Bookmark::from(params);
|
||||
assert_eq!(bookmark.protocol, FileTransferProtocol::Kube);
|
||||
assert!(bookmark.address.is_none());
|
||||
assert!(bookmark.port.is_none());
|
||||
assert!(bookmark.username.is_none());
|
||||
assert!(bookmark.password.is_none());
|
||||
let kube: &KubeParams = bookmark.kube.as_ref().unwrap();
|
||||
assert_eq!(kube.pod_name.as_str(), "pod");
|
||||
assert_eq!(kube.container.as_str(), "container");
|
||||
assert_eq!(kube.namespace.as_deref().unwrap(), "default");
|
||||
assert_eq!(
|
||||
kube.cluster_url.as_deref().unwrap(),
|
||||
"https://localhost:6443"
|
||||
);
|
||||
assert_eq!(kube.username.as_deref().unwrap(), "root");
|
||||
assert_eq!(kube.client_cert.as_deref().unwrap(), "cert");
|
||||
assert_eq!(kube.client_key.as_deref().unwrap(), "key");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ftparams_from_generic_bookmark() {
|
||||
let bookmark: Bookmark = Bookmark {
|
||||
@@ -390,6 +390,7 @@ mod tests {
|
||||
password: Some(String::from("password")),
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
};
|
||||
@@ -420,6 +421,7 @@ mod tests {
|
||||
password: Some(String::from("password")),
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
};
|
||||
@@ -449,6 +451,7 @@ mod tests {
|
||||
password: None,
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
kube: None,
|
||||
s3: Some(S3Params {
|
||||
bucket: String::from("veeso"),
|
||||
region: Some(String::from("eu-west-1")),
|
||||
@@ -480,6 +483,50 @@ mod tests {
|
||||
assert_eq!(gparams.new_path_style, true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ftparams_from_kube_bookmark() {
|
||||
let bookmark: Bookmark = Bookmark {
|
||||
protocol: FileTransferProtocol::Kube,
|
||||
address: None,
|
||||
port: None,
|
||||
username: None,
|
||||
password: None,
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
kube: Some(KubeParams {
|
||||
pod_name: String::from("pod"),
|
||||
container: String::from("container"),
|
||||
namespace: Some(String::from("default")),
|
||||
cluster_url: Some(String::from("https://localhost:6443")),
|
||||
username: Some(String::from("root")),
|
||||
client_cert: Some(String::from("cert")),
|
||||
client_key: Some(String::from("key")),
|
||||
}),
|
||||
s3: None,
|
||||
smb: None,
|
||||
};
|
||||
let params = FileTransferParams::from(bookmark);
|
||||
assert_eq!(params.protocol, FileTransferProtocol::Kube);
|
||||
assert_eq!(
|
||||
params.remote_path.as_deref().unwrap(),
|
||||
std::path::Path::new("/tmp")
|
||||
);
|
||||
assert_eq!(
|
||||
params.local_path.as_deref().unwrap(),
|
||||
std::path::Path::new("/usr")
|
||||
);
|
||||
let gparams = params.params.kube_params().unwrap();
|
||||
assert_eq!(gparams.pod.as_str(), "pod");
|
||||
assert_eq!(gparams.namespace.as_deref().unwrap(), "default");
|
||||
assert_eq!(
|
||||
gparams.cluster_url.as_deref().unwrap(),
|
||||
"https://localhost:6443"
|
||||
);
|
||||
assert_eq!(gparams.username.as_deref().unwrap(), "root");
|
||||
assert_eq!(gparams.client_cert.as_deref().unwrap(), "cert");
|
||||
assert_eq!(gparams.client_key.as_deref().unwrap(), "key");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn should_get_ftparams_from_smb_bookmark() {
|
||||
@@ -491,6 +538,7 @@ mod tests {
|
||||
password: Some("bar".to_string()),
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: Some(SmbParams {
|
||||
share: "test".to_string(),
|
||||
@@ -529,6 +577,7 @@ mod tests {
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
s3: None,
|
||||
kube: None,
|
||||
smb: Some(SmbParams {
|
||||
share: "test".to_string(),
|
||||
workgroup: None,
|
||||
|
||||
40
src/config/bookmarks/aws_s3.rs
Normal file
40
src/config/bookmarks/aws_s3.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::filetransfer::params::AwsS3Params;
|
||||
|
||||
/// Connection parameters for Aws s3 protocol
|
||||
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Default)]
|
||||
pub struct S3Params {
|
||||
pub bucket: String,
|
||||
pub region: Option<String>,
|
||||
pub endpoint: Option<String>,
|
||||
pub profile: Option<String>,
|
||||
pub access_key: Option<String>,
|
||||
pub secret_access_key: Option<String>,
|
||||
/// NOTE: there are no session token and security token since they are always temporary
|
||||
pub new_path_style: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<AwsS3Params> for S3Params {
|
||||
fn from(params: AwsS3Params) -> Self {
|
||||
S3Params {
|
||||
bucket: params.bucket_name,
|
||||
region: params.region,
|
||||
endpoint: params.endpoint,
|
||||
profile: params.profile,
|
||||
access_key: params.access_key,
|
||||
secret_access_key: params.secret_access_key,
|
||||
new_path_style: Some(params.new_path_style),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<S3Params> for AwsS3Params {
|
||||
fn from(params: S3Params) -> Self {
|
||||
AwsS3Params::new(params.bucket, params.region, params.profile)
|
||||
.endpoint(params.endpoint)
|
||||
.access_key(params.access_key)
|
||||
.secret_access_key(params.secret_access_key)
|
||||
.new_path_style(params.new_path_style.unwrap_or(false))
|
||||
}
|
||||
}
|
||||
43
src/config/bookmarks/kube.rs
Normal file
43
src/config/bookmarks/kube.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::filetransfer::params::KubeProtocolParams;
|
||||
|
||||
/// Extra Connection parameters for Kube protocol
|
||||
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Default)]
|
||||
pub struct KubeParams {
|
||||
pub pod_name: String,
|
||||
pub container: String,
|
||||
pub namespace: Option<String>,
|
||||
pub cluster_url: Option<String>,
|
||||
pub username: Option<String>,
|
||||
pub client_cert: Option<String>,
|
||||
pub client_key: Option<String>,
|
||||
}
|
||||
|
||||
impl From<KubeParams> for KubeProtocolParams {
|
||||
fn from(value: KubeParams) -> Self {
|
||||
Self {
|
||||
pod: value.pod_name,
|
||||
container: value.container,
|
||||
namespace: value.namespace,
|
||||
cluster_url: value.cluster_url,
|
||||
username: value.username,
|
||||
client_cert: value.client_cert,
|
||||
client_key: value.client_key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KubeProtocolParams> for KubeParams {
|
||||
fn from(value: KubeProtocolParams) -> Self {
|
||||
Self {
|
||||
pod_name: value.pod,
|
||||
container: value.container,
|
||||
namespace: value.namespace,
|
||||
cluster_url: value.cluster_url,
|
||||
username: value.username,
|
||||
client_cert: value.client_cert,
|
||||
client_key: value.client_key,
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/config/bookmarks/smb.rs
Normal file
30
src/config/bookmarks/smb.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::filetransfer::params::SmbParams as TransferSmbParams;
|
||||
|
||||
/// Extra Connection parameters for SMB protocol
|
||||
#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Eq, Default)]
|
||||
pub struct SmbParams {
|
||||
pub share: String,
|
||||
pub workgroup: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
impl From<TransferSmbParams> for SmbParams {
|
||||
fn from(params: TransferSmbParams) -> Self {
|
||||
Self {
|
||||
share: params.share,
|
||||
workgroup: params.workgroup,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
impl From<TransferSmbParams> for SmbParams {
|
||||
fn from(params: TransferSmbParams) -> Self {
|
||||
Self {
|
||||
share: params.share,
|
||||
workgroup: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ mod tests {
|
||||
use tuirealm::tui::style::Color;
|
||||
|
||||
use super::*;
|
||||
use crate::config::bookmarks::{Bookmark, S3Params, SmbParams, UserHosts};
|
||||
use crate::config::bookmarks::{Bookmark, KubeParams, S3Params, SmbParams, UserHosts};
|
||||
use crate::config::params::UserConfig;
|
||||
use crate::config::themes::Theme;
|
||||
use crate::filetransfer::FileTransferProtocol;
|
||||
@@ -366,7 +366,7 @@ mod tests {
|
||||
assert_eq!(host.username.as_deref().unwrap(), "root");
|
||||
assert_eq!(host.password, None);
|
||||
// Verify bookmarks
|
||||
assert_eq!(hosts.bookmarks.len(), 5);
|
||||
assert_eq!(hosts.bookmarks.len(), 6);
|
||||
let host: &Bookmark = hosts.bookmarks.get("raspberrypi2").unwrap();
|
||||
assert_eq!(host.address.as_deref().unwrap(), "192.168.1.31");
|
||||
assert_eq!(host.port.unwrap(), 22);
|
||||
@@ -404,6 +404,21 @@ mod tests {
|
||||
assert_eq!(s3.access_key.as_deref().unwrap(), "pippo");
|
||||
assert_eq!(s3.secret_access_key.as_deref().unwrap(), "pluto");
|
||||
assert_eq!(s3.new_path_style.unwrap(), true);
|
||||
// Kube pod
|
||||
let host: &Bookmark = hosts.bookmarks.get("pod").unwrap();
|
||||
assert_eq!(host.address, None);
|
||||
assert_eq!(host.port, None);
|
||||
assert_eq!(host.username, None);
|
||||
assert_eq!(host.password, None);
|
||||
assert_eq!(host.protocol, FileTransferProtocol::Kube);
|
||||
let kube = host.kube.as_ref().unwrap();
|
||||
assert_eq!(kube.pod_name.as_str(), "my-pod");
|
||||
assert_eq!(kube.container.as_str(), "my-container");
|
||||
assert_eq!(kube.namespace.as_deref().unwrap(), "my-namespace");
|
||||
assert_eq!(kube.cluster_url.as_deref().unwrap(), "https://my-cluster");
|
||||
assert_eq!(kube.username.as_deref().unwrap(), "my-username");
|
||||
assert_eq!(kube.client_cert.as_deref().unwrap(), "my-cert");
|
||||
assert_eq!(kube.client_key.as_deref().unwrap(), "my-key");
|
||||
|
||||
// smb
|
||||
let host = hosts.bookmarks.get("smb").unwrap();
|
||||
@@ -443,6 +458,7 @@ mod tests {
|
||||
password: None,
|
||||
remote_path: None,
|
||||
local_path: None,
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
},
|
||||
@@ -457,6 +473,7 @@ mod tests {
|
||||
password: Some(String::from("password")),
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
kube: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
},
|
||||
@@ -480,9 +497,35 @@ mod tests {
|
||||
secret_access_key: None,
|
||||
new_path_style: None,
|
||||
}),
|
||||
kube: None,
|
||||
smb: None,
|
||||
},
|
||||
);
|
||||
// push kube pod
|
||||
bookmarks.insert(
|
||||
String::from("pod"),
|
||||
Bookmark {
|
||||
address: None,
|
||||
port: None,
|
||||
protocol: FileTransferProtocol::Kube,
|
||||
username: None,
|
||||
password: None,
|
||||
remote_path: None,
|
||||
local_path: None,
|
||||
s3: None,
|
||||
smb: None,
|
||||
kube: Some(KubeParams {
|
||||
pod_name: "my-pod".to_string(),
|
||||
container: "my-container".to_string(),
|
||||
namespace: Some("my-namespace".to_string()),
|
||||
cluster_url: Some("https://my-cluster".to_string()),
|
||||
username: Some("my-username".to_string()),
|
||||
client_cert: Some("my-cert".to_string()),
|
||||
client_key: Some("my-key".to_string()),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
let smb_params: Option<SmbParams> = Some(SmbParams {
|
||||
share: "test".to_string(),
|
||||
workgroup: None,
|
||||
@@ -498,6 +541,7 @@ mod tests {
|
||||
remote_path: None,
|
||||
local_path: None,
|
||||
s3: None,
|
||||
kube: None,
|
||||
smb: smb_params,
|
||||
},
|
||||
);
|
||||
@@ -513,6 +557,7 @@ mod tests {
|
||||
remote_path: Some(PathBuf::from("/tmp")),
|
||||
local_path: Some(PathBuf::from("/usr")),
|
||||
s3: None,
|
||||
kube: None,
|
||||
smb: None,
|
||||
},
|
||||
);
|
||||
@@ -569,6 +614,17 @@ mod tests {
|
||||
secret_access_key = "pluto"
|
||||
new_path_style = true
|
||||
|
||||
[bookmarks.pod]
|
||||
protocol = "KUBE"
|
||||
[bookmarks.pod.kube]
|
||||
pod_name = "my-pod"
|
||||
container = "my-container"
|
||||
namespace = "my-namespace"
|
||||
cluster_url = "https://my-cluster"
|
||||
username = "my-username"
|
||||
client_cert = "my-cert"
|
||||
client_key = "my-key"
|
||||
|
||||
[bookmarks.smb]
|
||||
protocol = "SMB"
|
||||
address = "localhost"
|
||||
|
||||
Reference in New Issue
Block a user