Skip to content

Commit 4952b19

Browse files
committed
get stacker.rs version from dev branch
1 parent 4fec354 commit 4952b19

1 file changed

Lines changed: 0 additions & 188 deletions

File tree

src/commands/stacker.rs

Lines changed: 0 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,6 @@ pub enum StackerCommand {
695695
ListContainers(ListContainersCommand),
696696
ConfigureFirewall(ConfigureFirewallCommand),
697697
ProbeEndpoints(ProbeEndpointsCommand),
698-
CheckConnections(CheckConnectionsCommand),
699698
ActivatePipe(ActivatePipeCommand),
700699
DeactivatePipe(DeactivatePipeCommand),
701700
TriggerPipe(TriggerPipeCommand),
@@ -1705,23 +1704,6 @@ fn default_create_action() -> String {
17051704
"create".to_string()
17061705
}
17071706

1708-
/// Default HTTP/HTTPS ports checked when none are specified in `check_connections`.
1709-
#[cfg(feature = "docker")]
1710-
fn default_check_ports() -> Vec<u16> {
1711-
vec![80, 443, 8080, 3000, 8443]
1712-
}
1713-
1714-
/// Command to count active HTTP/HTTPS connections on the host.
1715-
#[cfg_attr(not(feature = "docker"), allow(dead_code))]
1716-
#[derive(Debug, Clone, Deserialize)]
1717-
pub struct CheckConnectionsCommand {
1718-
#[serde(default)]
1719-
deployment_hash: String,
1720-
/// Specific TCP ports to inspect. Defaults to common HTTP/HTTPS ports when omitted.
1721-
#[serde(default)]
1722-
ports: Option<Vec<u16>>,
1723-
}
1724-
17251707
pub fn parse_stacker_command(cmd: &AgentCommand) -> Result<Option<StackerCommand>> {
17261708
let normalized = cmd.name.trim().to_lowercase();
17271709
match normalized.as_str() {
@@ -1862,13 +1844,6 @@ pub fn parse_stacker_command(cmd: &AgentCommand) -> Result<Option<StackerCommand
18621844
payload.validate()?;
18631845
Ok(Some(StackerCommand::ProbeEndpoints(payload)))
18641846
}
1865-
"check_connections" | "stacker.check_connections" => {
1866-
let payload: CheckConnectionsCommand =
1867-
serde_json::from_value(unwrap_params(&cmd.params))
1868-
.context("invalid check_connections payload")?;
1869-
let payload = payload.normalize().with_command_context(cmd);
1870-
payload.validate()?;
1871-
Ok(Some(StackerCommand::CheckConnections(payload)))
18721847
"activate_pipe" | "stacker.activate_pipe" => {
18731848
let payload: ActivatePipeCommand = serde_json::from_value(unwrap_params(&cmd.params))
18741849
.context("invalid activate_pipe payload")?;
@@ -1905,12 +1880,6 @@ pub async fn execute_stacker_command(
19051880
return firewall::handle_configure_firewall(agent_cmd, data, firewall_policy).await;
19061881
}
19071882

1908-
// Connection check doesn't require Docker either
1909-
#[cfg(feature = "docker")]
1910-
if let StackerCommand::CheckConnections(data) = command {
1911-
return handle_check_connections(agent_cmd, data).await;
1912-
}
1913-
19141883
#[cfg(feature = "docker")]
19151884
{
19161885
execute_with_docker(agent_cmd, command, firewall_policy, pipe_runtime).await
@@ -2788,26 +2757,6 @@ impl ProbeEndpointsCommand {
27882757
}
27892758
}
27902759

2791-
impl CheckConnectionsCommand {
2792-
fn normalize(mut self) -> Self {
2793-
self.deployment_hash = trimmed(&self.deployment_hash);
2794-
self
2795-
}
2796-
2797-
fn with_command_context(mut self, agent_cmd: &AgentCommand) -> Self {
2798-
if self.deployment_hash.is_empty() {
2799-
if let Some(hash) = &agent_cmd.deployment_hash {
2800-
self.deployment_hash = hash.clone();
2801-
}
2802-
}
2803-
self
2804-
}
2805-
2806-
fn validate(&self) -> Result<()> {
2807-
Ok(())
2808-
}
2809-
}
2810-
28112760
fn trimmed(value: &str) -> String {
28122761
value.trim().to_string()
28132762
}
@@ -3264,7 +3213,6 @@ async fn execute_with_docker(
32643213
StackerCommand::ConfigureFirewall(data) => {
32653214
firewall::handle_configure_firewall(agent_cmd, data, firewall_policy).await
32663215
}
3267-
StackerCommand::CheckConnections(data) => handle_check_connections(agent_cmd, data).await,
32683216
}
32693217
}
32703218

@@ -8285,88 +8233,6 @@ async fn handle_probe_endpoints(
82858233
Ok(result)
82868234
}
82878235

8288-
#[cfg(feature = "docker")]
8289-
async fn handle_check_connections(
8290-
agent_cmd: &AgentCommand,
8291-
data: &CheckConnectionsCommand,
8292-
) -> Result<CommandResult> {
8293-
let mut result = base_result(agent_cmd, &data.deployment_hash, "", "check_connections");
8294-
8295-
let ports = data.ports.clone().unwrap_or_else(default_check_ports);
8296-
8297-
// Run `ss -Htn state established` to list established TCP connections.
8298-
// Output lines look like: "ESTAB 0 0 10.0.0.1:80 10.0.0.2:54321"
8299-
let output = tokio::process::Command::new("ss")
8300-
.args(["-Htn", "state", "established"])
8301-
.output()
8302-
.await;
8303-
8304-
let raw_lines = match output {
8305-
Ok(o) if o.status.success() => String::from_utf8_lossy(&o.stdout).to_string(),
8306-
Ok(o) => {
8307-
let stderr = String::from_utf8_lossy(&o.stderr).to_string();
8308-
let error = make_error("ss_failed", "Failed to run ss command", Some(stderr));
8309-
result.status = "error".to_string();
8310-
result.error = Some(error.message.clone());
8311-
result.errors = Some(vec![error]);
8312-
return Ok(result);
8313-
}
8314-
Err(e) => {
8315-
let error = make_error(
8316-
"ss_unavailable",
8317-
"ss command not available on this host",
8318-
Some(e.to_string()),
8319-
);
8320-
result.status = "error".to_string();
8321-
result.error = Some(error.message.clone());
8322-
result.errors = Some(vec![error]);
8323-
return Ok(result);
8324-
}
8325-
};
8326-
8327-
// Count connections per port.
8328-
let mut per_port: std::collections::HashMap<u16, u32> = ports.iter().map(|&p| (p, 0)).collect();
8329-
for line in raw_lines.lines() {
8330-
// Each token at position 3 (local addr:port) or 4 (peer addr:port) — we look at local.
8331-
// Columns: State Recv-Q Send-Q Local-Address:Port Peer-Address:Port
8332-
let parts: Vec<&str> = line.split_whitespace().collect();
8333-
if parts.len() < 4 {
8334-
continue;
8335-
}
8336-
let local = parts[3];
8337-
// Local may be "0.0.0.0:80" or "[::]:443" or "127.0.0.1:8080"
8338-
if let Some(port_str) = local.rsplit(':').next() {
8339-
if let Ok(port) = port_str.parse::<u16>() {
8340-
if let Some(count) = per_port.get_mut(&port) {
8341-
*count += 1;
8342-
}
8343-
}
8344-
}
8345-
}
8346-
8347-
let port_details: Vec<serde_json::Value> = per_port
8348-
.iter()
8349-
.map(|(&port, &connections)| json!({ "port": port, "connections": connections }))
8350-
.collect();
8351-
8352-
let active_connections: u32 = per_port.values().sum();
8353-
8354-
result.result = Some(json!({
8355-
"type": "check_connections",
8356-
"active_connections": active_connections,
8357-
"ports": port_details,
8358-
"ports_checked": ports,
8359-
"method": "ss",
8360-
"summary": format!(
8361-
"{} active HTTP connection(s) on {} port(s)",
8362-
active_connections,
8363-
ports.len()
8364-
),
8365-
}));
8366-
8367-
Ok(result)
8368-
}
8369-
83708236
#[cfg(test)]
83718237
mod tests {
83728238
use super::*;
@@ -9122,43 +8988,6 @@ mod tests {
91228988
assert!(parsed.is_none());
91238989
}
91248990

9125-
// ── check_connections ────────────────────────────
9126-
stacker_test!(
9127-
parses_check_connections_command_no_ports,
9128-
"check_connections",
9129-
json!({}),
9130-
StackerCommand::CheckConnections
9131-
);
9132-
stacker_test!(
9133-
parses_check_connections_command_with_ports,
9134-
"check_connections",
9135-
json!({ "ports": [80, 443, 8080] }),
9136-
StackerCommand::CheckConnections
9137-
);
9138-
stacker_test!(
9139-
parses_stacker_check_connections_command,
9140-
"stacker.check_connections",
9141-
json!({}),
9142-
StackerCommand::CheckConnections
9143-
);
9144-
9145-
#[test]
9146-
fn check_connections_ports_are_deserialized() {
9147-
let cmd = AgentCommand {
9148-
id: "cmd-cc".into(),
9149-
command_id: "cmd-cc".into(),
9150-
name: "check_connections".into(),
9151-
params: json!({ "ports": [80, 443] }),
9152-
deployment_hash: Some("hash-cc".into()),
9153-
app_code: None,
9154-
};
9155-
let parsed = parse_stacker_command(&cmd).unwrap().unwrap();
9156-
match parsed {
9157-
StackerCommand::CheckConnections(c) => {
9158-
assert_eq!(c.ports, Some(vec![80u16, 443u16]));
9159-
assert_eq!(c.deployment_hash, "hash-cc");
9160-
}
9161-
_ => panic!("expected CheckConnections variant"),
91628991
#[test]
91638992
fn parses_trigger_pipe_external_target_fields() {
91648993
let cmd = AgentCommand {
@@ -9195,23 +9024,6 @@ mod tests {
91959024
}
91969025

91979026
#[test]
9198-
fn check_connections_defaults_to_no_ports() {
9199-
let cmd = AgentCommand {
9200-
id: "cmd-cc2".into(),
9201-
command_id: "cmd-cc2".into(),
9202-
name: "check_connections".into(),
9203-
params: json!({}),
9204-
deployment_hash: Some("hash-cc2".into()),
9205-
app_code: None,
9206-
};
9207-
let parsed = parse_stacker_command(&cmd).unwrap().unwrap();
9208-
match parsed {
9209-
StackerCommand::CheckConnections(c) => {
9210-
assert!(c.ports.is_none(), "ports should be None when omitted");
9211-
}
9212-
_ => panic!("expected CheckConnections variant"),
9213-
}
9214-
}
92159027
fn parses_trigger_pipe_internal_target_fields() {
92169028
let cmd = AgentCommand {
92179029
id: "cmd-trigger".into(),

0 commit comments

Comments
 (0)