git.delta.rocks / jrsonnet / refs/commits / e862c17d93fb

difftreelog

feat support secrets without secret data

Yaroslav Bolyukin2021-11-13parent: #4ab80d6.patch.diff
in: trunk

4 files changed

modifiedcmds/fleet/src/cmds/secrets/mod.rsdiffbeforeafterboth
--- a/cmds/fleet/src/cmds/secrets/mod.rs
+++ b/cmds/fleet/src/cmds/secrets/mod.rs
@@ -70,17 +70,21 @@
 					let mut input = vec![];
 					io::stdin().read_to_end(&mut input)?;
 
-					let mut encrypted = vec![];
-					let recipients = recipients
-						.iter()
-						.cloned()
-						.map(|r| Box::new(r) as Box<dyn age::Recipient>)
-						.collect();
-					let mut encryptor =
-						age::Encryptor::with_recipients(recipients).wrap_output(&mut encrypted)?;
-					io::copy(&mut Cursor::new(input), &mut encryptor)?;
-					encryptor.finish()?;
-					encrypted
+					if input.is_empty() {
+						input
+					} else {
+						let mut encrypted = vec![];
+						let recipients = recipients
+							.iter()
+							.cloned()
+							.map(|r| Box::new(r) as Box<dyn age::Recipient>)
+							.collect();
+						let mut encryptor = age::Encryptor::with_recipients(recipients)
+							.wrap_output(&mut encrypted)?;
+						io::copy(&mut Cursor::new(input), &mut encryptor)?;
+						encryptor.finish()?;
+						encrypted
+					}
 				};
 
 				let mut data = config.data_mut();
modifiedcmds/fleet/src/fleetdata.rsdiffbeforeafterboth
--- a/cmds/fleet/src/fleetdata.rs
+++ b/cmds/fleet/src/fleetdata.rs
@@ -39,7 +39,12 @@
 	pub expire_at: Option<DateTime<Utc>>,
 	#[serde(skip_serializing_if = "Option::is_none")]
 	pub public: Option<String>,
-	#[serde(serialize_with = "as_z85", deserialize_with = "from_z85")]
+	#[serde(
+		default,
+		skip_serializing_if = "Vec::is_empty",
+		serialize_with = "as_z85",
+		deserialize_with = "from_z85"
+	)]
 	pub secret: Vec<u8>,
 }
 
modifiedcmds/install-secrets/src/main.rsdiffbeforeafterboth
--- a/cmds/install-secrets/src/main.rs
+++ b/cmds/install-secrets/src/main.rs
@@ -29,16 +29,21 @@
 	mode: String,
 	owner: String,
 	#[serde(deserialize_with = "from_z85")]
-	secret: Vec<u8>,
+	secret: Option<Vec<u8>>,
 }
 
-fn from_z85<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
+fn from_z85<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
 where
 	D: Deserializer<'de>,
 {
 	use serde::de::Error;
-	String::deserialize(deserializer)
-		.and_then(|string| z85::decode(&string).map_err(|err| Error::custom(err.to_string())))
+	if let Some(v) = <Option<String>>::deserialize(deserializer)? {
+		Ok(Some(
+			z85::decode(&v).map_err(|err| Error::custom(err.to_string()))?,
+		))
+	} else {
+		Ok(None)
+	}
 }
 
 type Data = HashMap<String, DataItem>;
@@ -49,6 +54,11 @@
 	name: &str,
 	value: DataItem,
 ) -> Result<()> {
+	if value.secret.is_none() {
+		return Ok(());
+	}
+	let secret = value.secret.as_ref().unwrap();
+
 	let mut path = dir.to_path_buf();
 	path.push(name);
 	if path.strip_prefix(&dir).is_err() {
@@ -88,7 +98,7 @@
 	// File is owned by root, and only root can modify it
 
 	let decrypted = {
-		let mut input = Cursor::new(&value.secret);
+		let mut input = Cursor::new(&secret);
 		let decryptor = Decryptor::new(&mut input).context("failed to init decryptor")?;
 		let decryptor = match decryptor {
 			Decryptor::Recipients(r) => r,
modifiedmodules/nixos/secrets.nixdiffbeforeafterboth
before · modules/nixos/secrets.nix
1{ lib, config, pkgs, ... }: with lib;2let3  sysConfig = config;4  secretType = types.submodule ({ config, ... }: {5    config = {6      path = mkOptionDefault "/run/secrets/${config._module.args.name}";7    };8    options = {9      public = mkOption {10        type = types.nullOr types.str;11        description = "Secret public data";12        default = null;13      };14      secret = mkOption {15        type = types.str;16        description = "Encrypted secret data";17      };18      mode = mkOption {19        type = types.str;20        description = "Secret mode";21        default = "0440";22      };23      owner = mkOption {24        type = types.str;25        description = "Owner of the secret";26        default = "root";27      };28      group = mkOption {29        type = types.str;30        description = "Group of the secret";31        default = sysConfig.users.users.${config.owner}.group;32      };3334      path = mkOption {35        type = types.str;36        readOnly = true;37        description = "Path to the decrypted secret";38      };39    };40  });41  secretsFile = pkgs.writeTextFile {42    name = "secrets.json";43    text = builtins.toJSON config.secrets;44  };45in46{47  options = {48    secrets = mkOption {49      type = types.attrsOf secretType;50      default = { };51      description = "Host-local secrets";52    };53  };54  config = {55    system.activationScripts.decryptSecrets = ''56      1>&2 echo "setting up secrets"57      ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets ${secretsFile}58    '';59  };60}
after · modules/nixos/secrets.nix
1{ lib, config, pkgs, ... }: with lib;2let3  sysConfig = config;4  secretType = types.submodule ({ config, ... }: {5    config = {6      path = mkOptionDefault (if config.secret == null then (error "secret is not set") else "/run/secrets/${config._module.args.name}");7      publicPath = mkOptionDefault (pkgs.writeText "pub-${config._module.args.name}" config.public);8      secret = mkIf (config.public != null) "";9    };10    options = {11      public = mkOption {12        type = types.nullOr types.str;13        description = "Secret public data";14        default = null;15      };16      secret = mkOption {17        type = types.nullOr types.str;18        description = "Encrypted secret data";19      };20      mode = mkOption {21        type = types.str;22        description = "Secret mode";23        default = "0440";24      };25      owner = mkOption {26        type = types.str;27        description = "Owner of the secret";28        default = "root";29      };30      group = mkOption {31        type = types.str;32        description = "Group of the secret";33        default = sysConfig.users.users.${config.owner}.group;34      };3536      path = mkOption {37        type = types.str;38        readOnly = true;39        description = "Path to the decrypted secret";40      };41      publicPath = mkOption {42        type = types.package;43        readOnly = true;44        description = "Path to the public part of secret";45      };46    };47  });48  secretsFile = pkgs.writeTextFile {49    name = "secrets.json";50    text = builtins.toJSON config.secrets;51  };52in53{54  options = {55    secrets = mkOption {56      type = types.attrsOf secretType;57      default = { };58      description = "Host-local secrets";59    };60  };61  config = {62    system.activationScripts.decryptSecrets = ''63      1>&2 echo "setting up secrets"64      ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets ${secretsFile}65    '';66  };67}