summaryrefslogtreecommitdiff
path: root/src/cloudinit.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2022-04-06 20:01:41 +0300
committerLars Wirzenius <liw@liw.fi>2022-04-07 10:13:02 +0300
commit7fb4d37e19469b1bf567dd57cb86ae9f9f9d44c0 (patch)
tree0c145eef6210cc711f054c77f127a8bf9877dc87 /src/cloudinit.rs
parentf5b7ee0ce079e22f37e42c23277ed32aebb41919 (diff)
downloadvmadm-7fb4d37e19469b1bf567dd57cb86ae9f9f9d44c0.tar.gz
feat: add a user_ca_pubkey field to config, spec
With this, there's no need to install an SSH key into root's authorized_keys file. Sponsored-by: author
Diffstat (limited to 'src/cloudinit.rs')
-rw-r--r--src/cloudinit.rs25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/cloudinit.rs b/src/cloudinit.rs
index 4fdf9d1..f5db9bf 100644
--- a/src/cloudinit.rs
+++ b/src/cloudinit.rs
@@ -44,7 +44,7 @@ log(f"loading user-data from {filename}")
obj = yaml.safe_load(open(filename))
ssh_keys = obj.get("ssh_keys", {})
-# log(f"ssh_keys: {json.dumps(ssh_keys)}")
+user_ca_pubkey = obj.get("user_ca_pubkey", {})
keys = []
certs = []
@@ -77,6 +77,11 @@ for key_type in key_types:
with open(filename, "w") as f:
f.write(cert)
+user_ca_filename = os.path.join(etc, "user-ca-keys")
+if user_ca_pubkey:
+ with open(user_ca_filename, "w") as f:
+ f.write(user_ca_pubkey)
+
config = os.path.join(etc, "sshd_config")
data = ""
if os.path.exists(config):
@@ -93,6 +98,9 @@ with open(config, "w") as f:
for filename in certs:
log(f"hostcert {filename}")
f.write(f"hostcertificate {filename}\n")
+ if user_ca_pubkey:
+ log(f"trustedusercakeys {user_ca_filename}")
+ f.write(f"trustedusercakeys {user_ca_filename}\n")
f.write(data)
log("vmadm cloud-init script ending")
@@ -118,6 +126,10 @@ pub enum CloudInitError {
#[error(transparent)]
KeyError(#[from] KeyError),
+ /// Something went wrong reading a file.
+ #[error("could not read {0}: {1}")]
+ ReadError(PathBuf, #[source] std::io::Error),
+
/// Something went wrong doing I/O.
#[error("could not write to {0}: {1}")]
WriteError(PathBuf, #[source] std::io::Error),
@@ -172,14 +184,25 @@ struct Userdata {
#[serde(skip_serializing_if = "Option::is_none")]
ssh_keys: Option<Hostkeys>,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ user_ca_pubkey: Option<String>,
+
runcmd: Vec<String>,
}
impl Userdata {
fn from(spec: &Specification) -> Result<Self, CloudInitError> {
+ let user_ca_pubkey = if let Some(filename) = &spec.user_ca_pubkey {
+ let data = std::fs::read(&filename)
+ .map_err(|err| CloudInitError::ReadError(filename.to_path_buf(), err))?;
+ Some(String::from_utf8(data)?)
+ } else {
+ None
+ };
Ok(Self {
ssh_authorized_keys: spec.ssh_keys.clone(),
ssh_keys: Hostkeys::from(spec)?,
+ user_ca_pubkey,
runcmd: vec![
format!("python3 -c {}", quote(SCRIPT)),
"systemctl reload ssh".to_string(),