-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexecutor_config.rs
More file actions
143 lines (134 loc) · 5.54 KB
/
Copy pathexecutor_config.rs
File metadata and controls
143 lines (134 loc) · 5.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! Builds the [`BrokerExecutor`] this binary serves. Moved verbatim (Phase 1
//! extraction) from the gateway's `routes/broker.rs::default_broker_executor`.
use std::sync::Arc;
use aegis_tool_broker_connectors::{
BrokerExecutor, ConnectorRegistry, FilesystemConnector, GithubConnector, GithubMode,
HttpConnector, ShellConnector,
};
use aegis_tool_broker_core::EnvCredentialResolver;
use tracing::error;
/// Builds the [`BrokerExecutor`] this process serves. GitHub runs in mock
/// mode unless `AEGIS_GITHUB_API_BASE` is set (real mode); `HttpConnector`
/// is always registered (HTTPS-only). The filesystem and shell connectors
/// are opt-in via `AEGIS_BROKER_WORKSPACE` — with no configured workspace
/// there is nothing safe to scope them to, so they're simply absent from
/// the registry (an execute against `filesystem`/`shell` then fails closed
/// with `UnknownConnectorType`, not a wide-open default).
pub fn build_broker_executor() -> Arc<BrokerExecutor> {
let github_mode = match std::env::var("AEGIS_GITHUB_API_BASE") {
Ok(base_url) if !base_url.trim().is_empty() => GithubMode::Real {
base_url: base_url.trim_end_matches('/').to_string(),
},
_ => GithubMode::Mock,
};
let mut registry = ConnectorRegistry::default()
.register(Arc::new(GithubConnector::new(github_mode)))
.register(Arc::new(HttpConnector::new()));
if let Ok(workspace) = std::env::var("AEGIS_BROKER_WORKSPACE") {
if !workspace.trim().is_empty() {
match FilesystemConnector::new(&workspace) {
Ok(fs) => registry = registry.register(Arc::new(fs)),
Err(e) => error!(
"AEGIS_BROKER_WORKSPACE {:?} unusable for filesystem connector: {}",
workspace, e
),
}
match ShellConnector::new(&workspace) {
Ok(shell) => registry = registry.register(Arc::new(shell)),
Err(e) => error!(
"AEGIS_BROKER_WORKSPACE {:?} unusable for shell connector: {}",
workspace, e
),
}
}
}
Arc::new(BrokerExecutor::new(
registry,
Arc::new(EnvCredentialResolver),
))
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn github_defaults_to_mock_mode_when_api_base_unset() {
std::env::remove_var("AEGIS_GITHUB_API_BASE");
std::env::remove_var("AEGIS_BROKER_WORKSPACE");
let executor = build_broker_executor();
// Mock mode never makes a real network call; a benign read must
// succeed synchronously without any credential configured.
let output = executor
.execute(
&aegis_tool_broker_connectors::BrokerToolBinding {
tool_name: "gh".to_string(),
connector_type: "github".to_string(),
credential_ref: None,
status: "active".to_string(),
},
&aegis_tool_broker_core::BrokerAction {
tool: "gh".to_string(),
action: "read".to_string(),
resource: None,
mutates_state: false,
parameters: serde_json::json!({"path": "/repos/acme/api/issues"}),
},
None,
)
.await;
assert!(output.is_ok());
}
#[tokio::test]
async fn filesystem_and_shell_are_absent_without_a_configured_workspace() {
std::env::remove_var("AEGIS_BROKER_WORKSPACE");
let executor = build_broker_executor();
let err = executor
.execute(
&aegis_tool_broker_connectors::BrokerToolBinding {
tool_name: "fs".to_string(),
connector_type: "filesystem".to_string(),
credential_ref: None,
status: "active".to_string(),
},
&aegis_tool_broker_core::BrokerAction {
tool: "fs".to_string(),
action: "read".to_string(),
resource: None,
mutates_state: false,
parameters: serde_json::json!({}),
},
None,
)
.await
.expect_err("filesystem must be unregistered without AEGIS_BROKER_WORKSPACE");
assert!(matches!(
err,
aegis_tool_broker_connectors::ExecuteError::UnknownConnectorType { .. }
));
}
#[tokio::test]
async fn filesystem_and_shell_are_registered_with_a_configured_workspace() {
let dir = tempfile::tempdir().unwrap();
std::env::set_var("AEGIS_BROKER_WORKSPACE", dir.path());
let executor = build_broker_executor();
let output = executor
.execute(
&aegis_tool_broker_connectors::BrokerToolBinding {
tool_name: "shell".to_string(),
connector_type: "shell".to_string(),
credential_ref: None,
status: "active".to_string(),
},
&aegis_tool_broker_core::BrokerAction {
tool: "shell".to_string(),
action: "run".to_string(),
resource: None,
mutates_state: false,
parameters: serde_json::json!({"command": ["/usr/bin/env"]}),
},
None,
)
.await;
assert!(output.is_ok());
std::env::remove_var("AEGIS_BROKER_WORKSPACE");
}
}