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

difftreelog

source

crates/fleet-base/src/secret.rs2.6 KiBsourcehistory
1use std::collections::BTreeSet;23use chrono::{DateTime, Utc};45use crate::fleetdata::FleetSecretData;67#[derive(Debug)]8pub struct Expectations {9	pub owners: BTreeSet<String>,10	pub generation_data: serde_json::Value,11	pub public_parts: BTreeSet<String>,12	pub private_parts: BTreeSet<String>,13}1415#[derive(thiserror::Error, Debug)]16pub enum RegenerationReason {17	#[error("owners added: {0:?}")]18	OwnersAdded(BTreeSet<String>),19	#[error("owners added: {0:?}")]20	OwnersRemoved(BTreeSet<String>),21	#[error("unexpected generation data, expected: {expected:?}, found: {found:?}")]22	GenerationData {23		expected: serde_json::Value,24		found: serde_json::Value,25	},26	#[error("unexpected part list, expected: {expected:?}, found: {found:?}")]27	PartList {28		expected: BTreeSet<String>,29		found: BTreeSet<String>,30	},31	#[error("part {0} is expected to be encrypted")]32	ExpectedPrivate(String),33	#[error("part {0} is not expected to be encrypted")]34	ExpectedPublic(String),35	#[error("secret is expired at {0}")]36	Expired(DateTime<Utc>),37}3839pub fn secret_needs_regeneration(40	secret: &FleetSecretData,41	owners: &BTreeSet<String>,42	expectations: &Expectations,43) -> Option<RegenerationReason> {44	if !owners.is_empty() {45		let added: BTreeSet<String> = expectations.owners.difference(owners).cloned().collect();46		if !added.is_empty() {47			return Some(RegenerationReason::OwnersAdded(added));48		}4950		let removed: BTreeSet<String> = owners.difference(&expectations.owners).cloned().collect();51		if !removed.is_empty() {52			return Some(RegenerationReason::OwnersRemoved(removed));53		}54	}5556	if secret.generation_data != expectations.generation_data {57		return Some(RegenerationReason::GenerationData {58			expected: expectations.generation_data.clone(),59			found: secret.generation_data.clone(),60		});61	}6263	if !expectations.public_parts.is_empty() || !expectations.private_parts.is_empty() {64		let expected: BTreeSet<String> = expectations65			.public_parts66			.union(&expectations.private_parts)67			.cloned()68			.collect();69		let found: BTreeSet<String> = secret.parts.keys().cloned().collect();7071		if found != expected {72			return Some(RegenerationReason::PartList { expected, found });73		}7475		for (name, value) in secret.parts.iter() {76			if value.raw.encrypted {77				if !expectations.private_parts.contains(name) {78					return Some(RegenerationReason::ExpectedPrivate(name.clone()));79				}80			} else if !expectations.public_parts.contains(name) {81				return Some(RegenerationReason::ExpectedPublic(name.clone()));82			}83		}84	}8586	if let Some(expiration) = secret.expires_at {87		// TODO: Leeway?88		if expiration < Utc::now() {89			return Some(RegenerationReason::Expired(expiration));90		}91	}9293	None94}