(ctx: PolicyPollLoopContext)
| 1618 | } |
| 1619 | |
| 1620 | async fn run_policy_poll_loop(ctx: PolicyPollLoopContext) -> Result<()> { |
| 1621 | use openshell_core::grpc_client::CachedOpenShellClient; |
| 1622 | use openshell_core::proto::PolicySource; |
| 1623 | use std::sync::atomic::Ordering; |
| 1624 | |
| 1625 | let client = CachedOpenShellClient::connect(&ctx.endpoint).await?; |
| 1626 | let mut current_config_revision: u64 = 0; |
| 1627 | let mut current_provider_env_revision: u64 = ctx.provider_credentials.snapshot().revision; |
| 1628 | let mut current_policy_hash = String::new(); |
| 1629 | let mut current_settings: std::collections::HashMap< |
| 1630 | String, |
| 1631 | openshell_core::proto::EffectiveSetting, |
| 1632 | > = std::collections::HashMap::new(); |
| 1633 | |
| 1634 | // Initialize revision from the first poll. |
| 1635 | match client.poll_settings(&ctx.sandbox_id).await { |
| 1636 | Ok(result) => { |
| 1637 | apply_ocsf_json_setting(&ctx.ocsf_enabled, &result.settings); |
| 1638 | current_config_revision = result.config_revision; |
| 1639 | current_policy_hash = result.policy_hash.clone(); |
| 1640 | current_settings = result.settings; |
| 1641 | debug!( |
| 1642 | config_revision = current_config_revision, |
| 1643 | "Settings poll: initial config revision" |
| 1644 | ); |
| 1645 | } |
| 1646 | Err(e) => { |
| 1647 | warn!(error = %e, "Settings poll: failed to fetch initial version, will retry"); |
| 1648 | } |
| 1649 | } |
| 1650 | |
| 1651 | let interval = Duration::from_secs(ctx.interval_secs); |
| 1652 | loop { |
| 1653 | tokio::time::sleep(interval).await; |
| 1654 | |
| 1655 | let result = match client.poll_settings(&ctx.sandbox_id).await { |
| 1656 | Ok(r) => r, |
| 1657 | Err(e) => { |
| 1658 | debug!(error = %e, "Settings poll: server unreachable, will retry"); |
| 1659 | continue; |
| 1660 | } |
| 1661 | }; |
| 1662 | |
| 1663 | let provider_env_changed = result.provider_env_revision != current_provider_env_revision; |
| 1664 | if result.config_revision == current_config_revision && !provider_env_changed { |
| 1665 | continue; |
| 1666 | } |
| 1667 | |
| 1668 | let policy_changed = result.policy_hash != current_policy_hash; |
| 1669 | |
| 1670 | // Log which settings changed. |
| 1671 | log_setting_changes(¤t_settings, &result.settings); |
| 1672 | |
| 1673 | ocsf_emit!(ConfigStateChangeBuilder::new(ocsf_ctx()) |
| 1674 | .severity(SeverityId::Informational) |
| 1675 | .status(StatusId::Success) |
| 1676 | .state(StateId::Other, "detected") |
| 1677 | .unmapped("old_config_revision", serde_json::json!(current_config_revision)) |
no test coverage detected