add cluster x kube-sign
This commit is contained in:
@ -5,7 +5,7 @@ edition = "2024"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bytes = "1.10.1"
|
bytes = "1.10.1"
|
||||||
clap = { version = "4.5.40", features = ["derive"] }
|
clap = { version = "4.5.40", features = ["derive", "env"] }
|
||||||
clap_complete = { version = "4.5.54", features = ["unstable-dynamic"] }
|
clap_complete = { version = "4.5.54", features = ["unstable-dynamic"] }
|
||||||
env_logger = "0.11.8"
|
env_logger = "0.11.8"
|
||||||
eyre = "0.6.12"
|
eyre = "0.6.12"
|
||||||
|
@ -45,11 +45,20 @@ enum ClusterCommand {
|
|||||||
user_public_key: String,
|
user_public_key: String,
|
||||||
#[arg(long, default_value = "root")]
|
#[arg(long, default_value = "root")]
|
||||||
principal: String,
|
principal: String,
|
||||||
#[arg(long, default_value = "+1d")]
|
#[arg(long, default_value = "1d")]
|
||||||
validity: String,
|
validity: String,
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
options: Vec<String>,
|
options: Vec<String>,
|
||||||
},
|
},
|
||||||
|
KubeSign {
|
||||||
|
csr: String,
|
||||||
|
#[arg(long, default_value = "anonymous", env = "USER")]
|
||||||
|
user: String,
|
||||||
|
#[arg(long)]
|
||||||
|
group: Option<String>,
|
||||||
|
#[arg(long, default_value = "1d")]
|
||||||
|
validity: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
@ -87,7 +96,7 @@ async fn main() -> Result<()> {
|
|||||||
}) => {
|
}) => {
|
||||||
let pub_key = tokio::fs::read_to_string(user_public_key).await?;
|
let pub_key = tokio::fs::read_to_string(user_public_key).await?;
|
||||||
let cert = cluster
|
let cert = cluster
|
||||||
.sign_ssh_user_pubkey(&dls::SshSignReq {
|
.ssh_userca_sign(&dls::SshSignReq {
|
||||||
pub_key,
|
pub_key,
|
||||||
principal,
|
principal,
|
||||||
validity: Some(validity).filter(|s| s != ""),
|
validity: Some(validity).filter(|s| s != ""),
|
||||||
@ -96,6 +105,23 @@ async fn main() -> Result<()> {
|
|||||||
.await?;
|
.await?;
|
||||||
write_raw(&cert);
|
write_raw(&cert);
|
||||||
}
|
}
|
||||||
|
Some(CC::KubeSign {
|
||||||
|
csr,
|
||||||
|
user,
|
||||||
|
group,
|
||||||
|
validity,
|
||||||
|
}) => {
|
||||||
|
let csr = tokio::fs::read_to_string(csr).await?;
|
||||||
|
let cert = cluster
|
||||||
|
.kube_sign(&dls::KubeSignReq {
|
||||||
|
csr,
|
||||||
|
user,
|
||||||
|
group,
|
||||||
|
validity: Some(validity).filter(|s| s != ""),
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
write_raw(&cert);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C::Hosts => write_json(&dls.hosts().await?),
|
C::Hosts => write_json(&dls.hosts().await?),
|
||||||
|
23
src/dls.rs
23
src/dls.rs
@ -96,7 +96,7 @@ impl<'t> Cluster<'t> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sign_ssh_user_pubkey(&self, sign_req: &SshSignReq) -> Result<Vec<u8>> {
|
pub async fn ssh_userca_sign(&self, sign_req: &SshSignReq) -> Result<Vec<u8>> {
|
||||||
let req = self.dls.req(
|
let req = self.dls.req(
|
||||||
Method::POST,
|
Method::POST,
|
||||||
format!("clusters/{}/ssh/user-ca/sign", self.name),
|
format!("clusters/{}/ssh/user-ca/sign", self.name),
|
||||||
@ -106,6 +106,14 @@ impl<'t> Cluster<'t> {
|
|||||||
let resp = do_req(req, &self.dls.token).await?;
|
let resp = do_req(req, &self.dls.token).await?;
|
||||||
Ok(resp.bytes().await.map_err(Error::Read)?.to_vec())
|
Ok(resp.bytes().await.map_err(Error::Read)?.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn kube_sign(&self, sign_req: &KubeSignReq) -> Result<Vec<u8>> {
|
||||||
|
let req = (self.dls).req(Method::POST, format!("clusters/{}/kube/sign", self.name))?;
|
||||||
|
let req = req.json(sign_req);
|
||||||
|
|
||||||
|
let resp = do_req(req, &self.dls.token).await?;
|
||||||
|
Ok(resp.bytes().await.map_err(Error::Read)?.to_vec())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Host<'t> {
|
pub struct Host<'t> {
|
||||||
@ -164,8 +172,21 @@ pub struct SshSignReq {
|
|||||||
pub options: Vec<String>,
|
pub options: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize, serde::Serialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct KubeSignReq {
|
||||||
|
#[serde(rename = "CSR")]
|
||||||
|
pub csr: String,
|
||||||
|
pub user: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub group: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub validity: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
struct ServerError {
|
struct ServerError {
|
||||||
|
#[serde(default)]
|
||||||
code: u16,
|
code: u16,
|
||||||
message: String,
|
message: String,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
Reference in New Issue
Block a user