Skip to content

Commit d629ad3

Browse files
committed
refactor: standardize network address handling with SocketAddr
- Update SshConnection struct to use SocketAddr instead of separate host_ip and port fields - Rename socket_addr field to ssh_socket_addr in RenderAnsibleTemplatesStep for clarity - Refactor validate_container_deployment_with_port to accept SocketAddr parameter - Update ssh_details() method in RunningProvisionedContainer to return SocketAddr - Standardize function signatures across SSH-related components to use SocketAddr - Maintain backward compatibility while providing cleaner, more consistent API
1 parent 73a43d2 commit d629ad3

File tree

16 files changed

+159
-161
lines changed

16 files changed

+159
-161
lines changed

src/application/commands/provision.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use crate::infrastructure::adapters::ansible::AnsibleClient;
2828
use crate::infrastructure::adapters::lxd::InstanceName;
2929
use crate::infrastructure::adapters::opentofu::client::{InstanceInfo, OpenTofuError};
3030
use crate::infrastructure::ansible::AnsibleTemplateRenderer;
31-
use crate::shared::executor::CommandError;
3231
use crate::infrastructure::tofu::{ProvisionTemplateError, TofuTemplateRenderer};
32+
use crate::shared::executor::CommandError;
3333
use crate::shared::ssh::{credentials::SshCredentials, SshError};
3434

3535
/// Comprehensive error type for the `ProvisionCommand`
@@ -146,11 +146,11 @@ impl ProvisionCommand {
146146
GetInstanceInfoStep::new(Arc::clone(&self.opentofu_client)).execute()?;
147147
let instance_ip = instance_info.ip_address;
148148

149+
let socket_addr = std::net::SocketAddr::new(instance_ip, 22); // Default SSH port for VMs
149150
RenderAnsibleTemplatesStep::new(
150151
Arc::clone(&self.ansible_template_renderer),
151152
self.ssh_credentials.clone(),
152-
instance_ip,
153-
22, // Default SSH port for VMs
153+
socket_addr,
154154
)
155155
.execute()
156156
.await?;

src/application/commands/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use crate::application::steps::{
2020
ValidateDockerComposeInstallationStep,
2121
ValidateDockerInstallationStep,
2222
};
23-
use crate::shared::executor::CommandError;
2423
use crate::infrastructure::remote_actions::RemoteActionError;
24+
use crate::shared::executor::CommandError;
2525
use crate::shared::ssh::credentials::SshCredentials;
2626

2727
/// Comprehensive error type for the `TestCommand`

src/application/steps/connectivity/wait_ssh_connectivity.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl WaitForSSHConnectivityStep {
5252
pub async fn execute(&self) -> Result<(), SshError> {
5353
info!(
5454
step = "wait_ssh_connectivity",
55-
instance_ip = %self.ssh_connection.host_ip,
55+
instance_ip = %self.ssh_connection.host_ip(),
5656
username = %self.ssh_connection.ssh_username(),
5757
"Waiting for SSH connectivity to be established"
5858
);
@@ -65,7 +65,7 @@ impl WaitForSSHConnectivityStep {
6565

6666
info!(
6767
step = "wait_ssh_connectivity",
68-
instance_ip = %self.ssh_connection.host_ip,
68+
instance_ip = %self.ssh_connection.host_ip(),
6969
status = "success",
7070
"SSH connectivity successfully established"
7171
);
@@ -99,7 +99,7 @@ mod tests {
9999
"/tmp/test_key"
100100
);
101101
assert_eq!(step.ssh_connection.ssh_username(), "testuser");
102-
assert_eq!(step.ssh_connection.host_ip, instance_ip);
102+
assert_eq!(step.ssh_connection.host_ip(), instance_ip);
103103
}
104104

105105
#[test]
@@ -119,7 +119,7 @@ mod tests {
119119
"/home/user/.ssh/id_rsa"
120120
);
121121
assert_eq!(step.ssh_connection.ssh_username(), "torrust");
122-
assert_eq!(step.ssh_connection.host_ip, instance_ip);
122+
assert_eq!(step.ssh_connection.host_ip(), instance_ip);
123123
}
124124

125125
#[test]
@@ -139,6 +139,6 @@ mod tests {
139139
"/path/to/ssh/key"
140140
);
141141
assert_eq!(step.ssh_connection.ssh_username(), "admin");
142-
assert_eq!(step.ssh_connection.host_ip, instance_ip);
142+
assert_eq!(step.ssh_connection.host_ip(), instance_ip);
143143
}
144144
}

src/application/steps/rendering/ansible_templates.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//! addresses are known, allowing for the generation of dynamic Ansible
1919
//! configurations for remote host management.
2020
21-
use std::net::IpAddr;
21+
use std::net::SocketAddr;
2222
use std::sync::Arc;
2323

2424
use thiserror::Error;
@@ -56,23 +56,20 @@ pub enum RenderAnsibleTemplatesError {
5656
pub struct RenderAnsibleTemplatesStep {
5757
ansible_template_renderer: Arc<AnsibleTemplateRenderer>,
5858
ssh_credentials: SshCredentials,
59-
instance_ip: IpAddr,
60-
ssh_port: u16,
59+
ssh_socket_addr: SocketAddr,
6160
}
6261

6362
impl RenderAnsibleTemplatesStep {
6463
#[must_use]
6564
pub fn new(
6665
ansible_template_renderer: Arc<AnsibleTemplateRenderer>,
6766
ssh_credentials: SshCredentials,
68-
instance_ip: IpAddr,
69-
ssh_port: u16,
67+
ssh_socket_addr: SocketAddr,
7068
) -> Self {
7169
Self {
7270
ansible_template_renderer,
7371
ssh_credentials,
74-
instance_ip,
75-
ssh_port,
72+
ssh_socket_addr,
7673
}
7774
}
7875

@@ -118,9 +115,9 @@ impl RenderAnsibleTemplatesStep {
118115
/// - SSH key path parsing fails
119116
/// - Inventory context creation fails
120117
fn create_inventory_context(&self) -> Result<InventoryContext, RenderAnsibleTemplatesError> {
121-
let host = AnsibleHost::from(self.instance_ip);
118+
let host = AnsibleHost::from(self.ssh_socket_addr.ip());
122119
let ssh_key = SshPrivateKeyFile::new(&self.ssh_credentials.ssh_priv_key_path)?;
123-
let ssh_port = AnsiblePort::new(self.ssh_port)?;
120+
let ssh_port = AnsiblePort::new(self.ssh_socket_addr.port())?;
124121

125122
InventoryContext::builder()
126123
.with_host(host)

src/application/steps/validation/cloud_init.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl ValidateCloudInitCompletionStep {
6262
let cloud_init_validator = CloudInitValidator::new(self.ssh_connection.clone());
6363

6464
cloud_init_validator
65-
.execute(&self.ssh_connection.host_ip)
65+
.execute(&self.ssh_connection.host_ip())
6666
.await?;
6767

6868
Ok(())
@@ -91,6 +91,6 @@ mod tests {
9191
let step = ValidateCloudInitCompletionStep::new(ssh_connection);
9292

9393
// Test that the step can be created successfully
94-
assert_eq!(step.ssh_connection.host_ip, host_ip);
94+
assert_eq!(step.ssh_connection.host_ip(), host_ip);
9595
}
9696
}

src/application/steps/validation/docker.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl ValidateDockerInstallationStep {
6161
let docker_validator = DockerValidator::new(self.ssh_connection.clone());
6262

6363
docker_validator
64-
.execute(&self.ssh_connection.host_ip)
64+
.execute(&self.ssh_connection.host_ip())
6565
.await?;
6666

6767
Ok(())
@@ -90,6 +90,6 @@ mod tests {
9090
let step = ValidateDockerInstallationStep::new(ssh_connection);
9191

9292
// Test that the step can be created successfully
93-
assert_eq!(step.ssh_connection.host_ip, host_ip);
93+
assert_eq!(step.ssh_connection.host_ip(), host_ip);
9494
}
9595
}

src/application/steps/validation/docker_compose.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl ValidateDockerComposeInstallationStep {
6767
let docker_compose_validator = DockerComposeValidator::new(self.ssh_connection.clone());
6868

6969
docker_compose_validator
70-
.execute(&self.ssh_connection.host_ip)
70+
.execute(&self.ssh_connection.host_ip())
7171
.await?;
7272

7373
Ok(())
@@ -96,6 +96,6 @@ mod tests {
9696
let step = ValidateDockerComposeInstallationStep::new(ssh_connection);
9797

9898
// Test that the step can be created successfully
99-
assert_eq!(step.ssh_connection.host_ip, host_ip);
99+
assert_eq!(step.ssh_connection.host_ip(), host_ip);
100100
}
101101
}

src/bin/e2e_config_tests.rs

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
2626
use anyhow::{Context, Result};
2727
use clap::Parser;
28+
use std::net::SocketAddr;
2829
use std::sync::Arc;
2930
use std::time::{Duration, Instant};
3031
use tokio::runtime::Runtime;
@@ -147,10 +148,10 @@ fn run_configuration_tests() -> Result<()> {
147148
.context("Failed to start provisioned instance container")?;
148149

149150
// Step 2: Wait for SSH server and setup connectivity (only available when running)
150-
let (ssh_host, ssh_port) = running_container.ssh_details();
151+
let socket_addr = running_container.ssh_details();
151152
let ssh_wait_action = SshWaitAction::new(Duration::from_secs(30), 10);
152153
ssh_wait_action
153-
.execute(&ssh_host, ssh_port)
154+
.execute(socket_addr)
154155
.context("SSH server failed to start")?;
155156

156157
// Get SSH credentials from test environment and setup keys
@@ -161,8 +162,7 @@ fn run_configuration_tests() -> Result<()> {
161162
.context("Failed to setup SSH authentication")?;
162163

163164
info!(
164-
ssh_host = %ssh_host,
165-
ssh_port = ssh_port,
165+
socket_addr = %socket_addr,
166166
ssh_user = %ssh_credentials.ssh_username,
167167
container_id = %running_container.container_id(),
168168
"Container ready for Ansible configuration"
@@ -194,11 +194,10 @@ fn run_configuration_tests() -> Result<()> {
194194
async fn run_provision_simulation(
195195
running_container: &torrust_tracker_deploy::e2e::containers::RunningProvisionedContainer,
196196
) -> Result<()> {
197-
let (ssh_host, ssh_port) = running_container.ssh_details();
197+
let socket_addr = running_container.ssh_details();
198198

199199
info!(
200-
ssh_host = %ssh_host,
201-
ssh_port = ssh_port,
200+
socket_addr = %socket_addr,
202201
"Running provision simulation for container"
203202
);
204203

@@ -211,8 +210,7 @@ async fn run_provision_simulation(
211210
provision_docker_infrastructure(
212211
Arc::clone(&services.ansible_template_renderer),
213212
ssh_credentials,
214-
ssh_host.parse()?,
215-
ssh_port,
213+
socket_addr,
216214
)
217215
.await
218216
.context("Failed to complete Docker infrastructure provision simulation")?;
@@ -229,11 +227,10 @@ async fn run_provision_simulation(
229227
fn run_ansible_configuration(
230228
running_container: &torrust_tracker_deploy::e2e::containers::RunningProvisionedContainer,
231229
) -> Result<()> {
232-
let (ssh_host, ssh_port) = running_container.ssh_details();
230+
let socket_addr = running_container.ssh_details();
233231

234232
info!(
235-
ssh_host = %ssh_host,
236-
ssh_port = ssh_port,
233+
socket_addr = %socket_addr,
237234
"Running Ansible configuration on container"
238235
);
239236

@@ -291,11 +288,10 @@ fn run_ansible_configuration(
291288
async fn run_deployment_validation(
292289
running_container: &torrust_tracker_deploy::e2e::containers::RunningProvisionedContainer,
293290
) -> Result<()> {
294-
let (ssh_host, ssh_port) = running_container.ssh_details();
291+
let socket_addr = running_container.ssh_details();
295292

296293
info!(
297-
ssh_host = %ssh_host,
298-
ssh_port = ssh_port,
294+
socket_addr = %socket_addr,
299295
"Running deployment validation on container"
300296
);
301297

@@ -304,10 +300,7 @@ async fn run_deployment_validation(
304300
match credentials_result {
305301
Ok(ssh_credentials) => {
306302
// Create SSH connection with the container's dynamic port
307-
let host_ip = ssh_host.parse().context("Failed to parse SSH host as IP")?;
308-
309-
match validate_container_deployment_with_port(&ssh_credentials, host_ip, ssh_port).await
310-
{
303+
match validate_container_deployment_with_port(&ssh_credentials, socket_addr).await {
311304
Ok(()) => {
312305
info!(status = "success", "All deployment validations passed");
313306
}
@@ -378,29 +371,30 @@ fn create_container_ssh_credentials() -> Result<SshCredentials> {
378371
/// Validate container deployment using SSH infrastructure with custom port
379372
async fn validate_container_deployment_with_port(
380373
ssh_credentials: &SshCredentials,
381-
host_ip: std::net::IpAddr,
382-
ssh_port: u16,
374+
socket_addr: SocketAddr,
383375
) -> Result<()> {
384376
use torrust_tracker_deploy::infrastructure::remote_actions::{
385377
DockerComposeValidator, DockerValidator, RemoteAction,
386378
};
387379

380+
let ip_addr = socket_addr.ip();
381+
388382
// Create SSH connection with the container's dynamic port using the new port support
389383
let ssh_connection = ssh_credentials
390384
.clone()
391-
.with_host_and_port(host_ip, ssh_port);
385+
.with_host_and_port(ip_addr, socket_addr.port());
392386

393387
// Validate Docker installation
394388
let docker_validator = DockerValidator::new(ssh_connection.clone());
395389
docker_validator
396-
.execute(&host_ip)
390+
.execute(&ip_addr)
397391
.await
398392
.context("Docker validation failed")?;
399393

400394
// Validate Docker Compose installation
401395
let compose_validator = DockerComposeValidator::new(ssh_connection);
402396
compose_validator
403-
.execute(&host_ip)
397+
.execute(&ip_addr)
404398
.await
405399
.context("Docker Compose validation failed")?;
406400

src/e2e/containers/actions/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,20 @@
2222
//! use torrust_tracker_deploy::e2e::containers::{ContainerExecutor, actions::{SshKeySetupAction, SshWaitAction}};
2323
//! use torrust_tracker_deploy::shared::ssh::SshCredentials;
2424
//! use std::time::Duration;
25+
//! use std::net::SocketAddr;
2526
//!
2627
//! fn setup_container_ssh<T: ContainerExecutor>(
2728
//! container: &T,
2829
//! ssh_credentials: &SshCredentials,
29-
//! host: &str,
30-
//! port: u16,
30+
//! socket_addr: SocketAddr,
3131
//! ) -> Result<(), Box<dyn std::error::Error>> {
3232
//! // Setup SSH keys inside the container
3333
//! let ssh_setup = SshKeySetupAction::new();
3434
//! ssh_setup.execute(container, ssh_credentials)?;
3535
//!
3636
//! // Wait for SSH to be accessible
3737
//! let ssh_wait = SshWaitAction::new(Duration::from_secs(30), 10);
38-
//! ssh_wait.execute(host, port)?;
38+
//! ssh_wait.execute(socket_addr)?;
3939
//!
4040
//! Ok(())
4141
//! }

0 commit comments

Comments
 (0)