Allow selecting ssh user dynamically

...by setting `deployment.targetUser = null`.

This allows sharing a deployment file (hive.nix/flake.nix) between
multiple admins, without having to use a shared root account.
This commit is contained in:
Bjørn Forsman 2021-10-23 13:22:35 +02:00
parent d0c89302be
commit 4106a73e75
5 changed files with 25 additions and 6 deletions

11
Cargo.lock generated
View file

@ -133,6 +133,7 @@ dependencies = [
"tempfile", "tempfile",
"tokio", "tokio",
"tokio-test", "tokio-test",
"users",
"validator", "validator",
] ]
@ -890,6 +891,16 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "users"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
dependencies = [
"libc",
"log",
]
[[package]] [[package]]
name = "validator" name = "validator"
version = "0.12.0" version = "0.12.0"

View file

@ -27,6 +27,7 @@ sys-info = "0.7.0"
snafu = "0.6.10" snafu = "0.6.10"
tempfile = "3.1.0" tempfile = "3.1.0"
tokio-test = "0.4.0" tokio-test = "0.4.0"
users = "0.11.0"
validator = { version = "0.12", features = ["derive"] } validator = { version = "0.12", features = ["derive"] }
[dependencies.tokio] [dependencies.tokio]

View file

@ -113,9 +113,10 @@ let
}; };
targetUser = lib.mkOption { targetUser = lib.mkOption {
description = '' description = ''
The user to use to log into the remote node. The user to use to log into the remote node. If null, login as the
current user.
''; '';
type = types.str; type = types.nullOr types.str;
default = "root"; default = "root";
}; };
allowLocalDeployment = lib.mkOption { allowLocalDeployment = lib.mkOption {

View file

@ -9,6 +9,7 @@ use serde::de::DeserializeOwned;
use serde::Deserialize; use serde::Deserialize;
use snafu::Snafu; use snafu::Snafu;
use tokio::process::Command; use tokio::process::Command;
use users::get_current_username;
use validator::{Validate, ValidationErrors, ValidationError as ValidationErrorType}; use validator::{Validate, ValidationErrors, ValidationError as ValidationErrorType};
use crate::util::CommandExecution; use crate::util::CommandExecution;
@ -115,7 +116,7 @@ pub struct NodeConfig {
target_host: Option<String>, target_host: Option<String>,
#[serde(rename = "targetUser")] #[serde(rename = "targetUser")]
target_user: String, target_user: Option<String>,
#[serde(rename = "targetPort")] #[serde(rename = "targetPort")]
target_port: Option<u16>, target_port: Option<u16>,
@ -140,7 +141,12 @@ impl NodeConfig {
pub fn to_ssh_host(&self) -> Option<Ssh> { pub fn to_ssh_host(&self) -> Option<Ssh> {
self.target_host.as_ref().map(|target_host| { self.target_host.as_ref().map(|target_host| {
let mut host = Ssh::new(self.target_user.clone(), target_host.clone()); let username =
match &self.target_user {
Some(uname) => uname.clone(),
None => get_current_username().unwrap().into_string().ok().unwrap(),
};
let mut host = Ssh::new(username.clone(), target_host.clone());
host.set_privilege_escalation_command(self.privilege_escalation_command.clone()); host.set_privilege_escalation_command(self.privilege_escalation_command.clone());
if let Some(target_port) = self.target_port { if let Some(target_port) = self.target_port {

View file

@ -134,7 +134,7 @@ fn test_parse_simple() {
)); ));
assert_eq!(Some("host-a"), nodes["host-a"].target_host.as_deref()); assert_eq!(Some("host-a"), nodes["host-a"].target_host.as_deref());
assert_eq!(None, nodes["host-a"].target_port); assert_eq!(None, nodes["host-a"].target_port);
assert_eq!("root", &nodes["host-a"].target_user); assert_eq!(Some("root"), nodes["host-a"].target_user.as_deref());
// host-b // host-b
assert!(set_eq( assert!(set_eq(
@ -143,7 +143,7 @@ fn test_parse_simple() {
)); ));
assert_eq!(Some("somehost.tld"), nodes["host-b"].target_host.as_deref()); assert_eq!(Some("somehost.tld"), nodes["host-b"].target_host.as_deref());
assert_eq!(Some(1234), nodes["host-b"].target_port); assert_eq!(Some(1234), nodes["host-b"].target_port);
assert_eq!("luser", &nodes["host-b"].target_user); assert_eq!(Some("luser"), nodes["host-b"].target_user.as_deref());
} }
#[test] #[test]