#![allow(dead_code)] use std::sync::Arc; use std::time::{Duration, Instant}; use anyhow::Result; use serde::{Deserialize, Serialize}; use tokio::sync::RwLock; use tracing::info; use crate::discovery::ServiceDiscovery; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PolicyDecision { pub allow: bool, pub mode: String, // mtls/tls/plain pub reason: String, } pub struct PolicyEnforcer { discovery: Arc, default_mode: String, cache: Arc>>, } impl PolicyEnforcer { pub fn new(discovery: Arc, default_mode: String) -> Self { Self { discovery, default_mode, cache: Arc::new(RwLock::new(std::collections::HashMap::new())), } } pub async fn evaluate( &self, source_service: &str, target_service: &str, ) -> Result { let cache_key = format!("{}->{}", source_service, target_service); // キャッシュをチェック { let cache = self.cache.read().await; if let Some((decision, timestamp)) = cache.get(&cache_key) { if timestamp.elapsed() < Duration::from_secs(30) { return Ok(decision.clone()); } } } // Chainfireからポリシーを取得 let policy = self .discovery .get_mtls_policy(source_service, target_service) .await?; let decision = if let Some(p) = policy { PolicyDecision { allow: true, mode: p.mode.unwrap_or_else(|| { if p.mtls_required.unwrap_or(false) { "mtls".to_string() } else { "plain".to_string() } }), reason: format!("policy {} applied", p.policy_id), } } else { PolicyDecision { allow: true, mode: self.default_mode.clone(), reason: "default policy applied".to_string(), } }; // キャッシュに保存 { let mut cache = self.cache.write().await; cache.insert(cache_key, (decision.clone(), Instant::now())); } info!( source = source_service, target = target_service, mode = %decision.mode, "policy decision" ); Ok(decision) } pub async fn start_background_refresh(&self) { let cache = Arc::clone(&self.cache); tokio::spawn(async move { let mut interval = tokio::time::interval(Duration::from_secs(60)); loop { interval.tick().await; // キャッシュをクリア(簡易実装) { let mut cache_guard = cache.write().await; cache_guard.clear(); } info!("policy cache cleared, will be refreshed on next request"); } }); } }