# SSH Module Examples


### SSH Connection Pattern

The SSH module uses a **Connection Pattern** for creating connections and managing operations.

```rust
// Create connection
let conn = SshConnection::new()
    .host("server.example.com")
    .user("admin")
    .port(22)
    .ssh_private_key_path("/home/user/.ssh/id_rsa")
    .timeout_secs(10)
    .connect();
```

### SshConnection Methods

- `execute(cmd)` - Execute command and return (exit_code, output)
- `ping()` - Test SSH connectivity (returns bool)
- `file_transfer()` - Create a FileTransferBuilder for rsync operations

### FileTransferBuilder Methods

- `archive(bool)` - Preserve permissions and times (-a flag)
- `verbose(bool)` - Enable verbose output (-v flag)
- `compress(bool)` - Compress during transfer (-z flag)
- `delete(bool)` - Delete remote files not in source
- `exclude(pattern)` - Add single exclude pattern
- `exclude_patterns(vec![...])` - Add multiple exclude patterns
- `push(local, remote)` - Upload files to remote
- `pull(remote, local)` - Download files from remote

## Examples

| File | Description | Use Case |
|------|-------------|----------|
| `03_ssh_builder_basics.rhai` | **SSH Connection Pattern basics** - Quick start guide | Learn SSH connection pattern fundamentals |
| `08_ssh_builder_pattern.rhai` | **Comprehensive SSH Guide** - connection pattern details | Complete SSH connection pattern reference |
| `09_ssh_refactoring_guide.md` | **Architecture guide** - SSH module design | Understanding the connection pattern architecture |

## Example Details

### 03_ssh_builder_basics.rhai

**SSH Connection Pattern Quick Start** - Modern SSH operations using connection pattern. Demonstrates:

- Creating SSH connections with `SshConnection::new().connect()`
- SSH key support with `.ssh_private_key_path()`
- Executing remote commands with `.execute()`
- Testing connectivity with `.ping()`
- **File Transfer Builder** - Declarative rsync operations
  - Upload (push): `.push(local_path, remote_path)`
  - Download (pull): `.pull(remote_path, local_path)`
  - Options: archive, verbose, compress, exclude patterns, delete
- **Configuration Options**
  - Host, user, port, identity file, timeout
  - Chainable builder methods
  - Default values with overrides
- **Practical Examples**
  - Deployment workflows
  - Backup operations
  - Multi-pattern exclusions
- **Best Practices**
  - Using SSH keys instead of passwords
  - Error handling patterns
  - Timeout configuration
  - Testing before operations

### 08_ssh_builder_pattern.rhai

**Comprehensive SSH Guide** - Complete reference for SSH connection pattern. Demonstrates:

- Complete SshConnection API reference
- All configuration options
- Command execution patterns
- File transfer operations
- Advanced configuration scenarios
- Error handling strategies

### 09_ssh_refactoring_guide.md

**Architecture guide** - In-depth documentation of the SSH module refactoring. Includes:

- Before/after architecture comparison
- Builder pattern usage examples
- API reference documentation
- Migration guide from old to new API
- Key features explanation
- Internal implementation details
- Testing and usage patterns

## Running Examples

```bash
# Run individual examples
herodo packages/os/rhaiexamples/ssh/03_ssh_builder_basics.rhai

# Run comprehensive guide
herodo packages/os/rhaiexamples/ssh/08_ssh_builder_pattern.rhai

# Run all SSH examples
for file in packages/os/rhaiexamples/ssh/*.rhai; do
    echo "Running $file..."
    herodo "$file"
done
```

## Configuration Notes

### SSH Key Setup

- Requires SSH keys configured for authentication
- Specify key path with `.ssh_private_key_path("/path/to/key")`
- Supports standard OpenSSH key formats
- Permissions should be 600 for key files

### Connection Options

- **Host**: Hostname or IP address
- **User**: SSH username
- **Port**: SSH port (default: 22)
- **Identity File**: Path to SSH private key
- **Timeout**: Connection timeout in seconds (default: 10)

### File Transfer Options

| Option | Builder Method | Description |
|--------|----------------|-------------|
| -a | `.archive(true)` | Preserve permissions, times, etc. |
| -v | `.verbose(true)` | Show verbose output |
| -z | `.compress(true)` | Compress during transfer |
| --delete | `.delete(true)` | Delete dest files not in source |
| --exclude | `.exclude(pattern)` | Exclude single pattern |
| --exclude | `.exclude_patterns(vec![...])` | Exclude multiple patterns |

## API Reference

### SshConnection Creation

| Method | Type | Default | Description |
|--------|------|---------|-------------|
| `host()` | String | "localhost" | Target hostname or IP |
| `user()` | String | "root" | SSH username |
| `port()` | u16 | 22 | SSH port |
| `ssh_private_key_path()` | PathBuf | None | SSH private key path |
| `timeout_secs()` | u64 | 10 | Connection timeout |
| `timeout()` | Duration | 10s | Connection timeout |
| `connect()` | → SshConnection | - | Establish the connection |

### SshConnection

| Method | Returns | Description |
|--------|---------|-------------|
| `execute(cmd)` | `Result<(i32, String)>` | Execute command, return exit code and output |
| `ping()` | `Result<bool>` | Test SSH connectivity |
| `file_transfer()` | FileTransferBuilder | Create file transfer builder |

### FileTransferBuilder

| Method | Type | Default | Description |
|--------|------|---------|-------------|
| `archive()` | bool | true | Preserve permissions/times (-a) |
| `verbose()` | bool | true | Verbose output (-v) |
| `compress()` | bool | true | Compress in transit (-z) |
| `delete()` | bool | false | Delete dest files not in source |
| `exclude()` | String | - | Add single exclude pattern |
| `exclude_patterns()` | Vec<String> | - | Add multiple patterns |
| `push()` | → Result | - | Upload from local to remote |
| `pull()` | → Result | - | Download from remote to local |

## Usage Patterns

### Basic Connection

```rust
let conn = SshConnection::new()
    .host("remote-server.example.com")
    .user("admin")
    .port(22)
    .connect();

if conn.ping()? {
    println!("Connected!");
}

let (code, output) = conn.execute("ls -la")?;
```

### Connection with SSH Key

```rust
let conn = SshConnection::new()
    .host("deploy-server.com")
    .user("deploy")
    .port(22)
    .ssh_private_key_path("/home/user/.ssh/deploy_key")
    .timeout_secs(10)
    .connect();

let (code, output) = conn.execute("whoami")?;
```

### File Transfers

```rust
let conn = SshConnection::new()
    .host("backup-server.com")
    .user("backup")
    .ssh_private_key_path("/home/user/.ssh/backup_key")
    .connect();

// Push (upload) files
let transfer = conn.file_transfer()
    .archive(true)
    .compress(true)
    .exclude("*.log")
    .exclude(".git");

let (code, output) = transfer.push("./app", "/opt/app")?;

// Pull (download) files
let (code, output) = transfer.pull("/backups/db", "./local_backups")?;
```

### Advanced Configuration

```rust
let conn = SshConnection::new()
    .host("server.example.com")
    .user("admin")
    .ssh_private_key_path("/home/user/.ssh/id_rsa")
    .port(2222)
    .timeout_secs(30)
    .connect();

let transfer = conn.file_transfer()
    .archive(true)
    .verbose(true)
    .compress(true)
    .delete(true)
    .exclude_patterns(vec![
        "*.log",
        ".git",
        "node_modules",
        ".tmp"
    ]);

let (code, _) = transfer.push("./src", "/opt/myapp/src")?;
```

## Best Practices

1. **Reuse Connections**
   ```rust
   let conn = SshConnection::new()
       .host("server.com")
       .user("admin")
       .connect();
   
   for cmd in commands {
       conn.execute(cmd)?;
   }
   ```

2. **Use SSH Keys**
   ```rust
   let conn = SshConnection::new()
       .ssh_private_key_path("/home/user/.ssh/deploy_key")
       .connect();
   ```

3. **Handle Timeouts**
   ```rust
   let conn = SshConnection::new()
       .timeout_secs(30)
       .connect();
   ```

4. **Exclude Patterns in Transfers**
   ```rust
   let transfer = conn.file_transfer()
       .exclude_patterns(vec![
           "*.log", ".git", "node_modules"
       ]);
   ```

5. **Error Handling**
   ```rust
   match conn.execute("ls") {
       Ok((0, output)) => println!("Success: {}", output),
       Ok((code, _)) => println!("Command failed with code {}", code),
       Err(e) => println!("Error: {}", e),
   }
   ```

## Key Features

### 1. SSH Key Support

```rust
// Specify SSH key for authentication
let conn = SshConnection::new()
    .ssh_private_key_path("/home/user/.ssh/id_rsa")
    .connect();
```

### 2. Connection Reuse

```rust
// Single connection for multiple operations
let conn = SshConnection::new()
    .host("server.com")
    .user("admin")
    .connect();

conn.ping()?;
conn.execute("cmd1")?;
conn.execute("cmd2")?;
let (_, _) = conn.file_transfer().push("src", "dest")?;
```

### 3. Chainable Configuration

```rust
// Fluent API for readable configuration
let transfer = conn.file_transfer()
    .archive(true)
    .verbose(true)
    .compress(true)
    .exclude("*.log")
    .exclude(".git");
```

### 4. Type-Safe Operations

```rust
// Compiler ensures correct usage
let conn = SshConnection::new()
    .host("server")
    .user("admin")
    .connect();
// Type system ensures these methods exist
conn.execute("cmd")?;
conn.ping()?;
```

## Security Notes

- **SSH Keys**: Always use SSH key-based authentication instead of passwords
- **Key Permissions**: Ensure SSH keys have 600 permissions
- **Known Hosts**: Configure SSH known_hosts file or use SSH options appropriately
- **Firewall**: Restrict SSH access with firewall rules
- **Logging**: Monitor SSH access logs for suspicious activity
- **Key Rotation**: Regularly rotate SSH keys

## Performance Considerations

- Connection reuse is more efficient than creating new connections
- Batch file operations together to minimize round-trips
- Use exclude patterns to avoid transferring unnecessary files
- Compression (-z flag) is useful for slow networks
- Archive mode (-a) is essential for preserving file attributes

## Architecture

The SSH module provides a clean abstraction over SSH operations:

```
┌─────────────────────────────────────────────────────────────────┐
│  SshConnection (Main Interface)                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────────────────┐  ┌──────────────────────┐            │
│  │ SshConnectionBuilder  │  │ FileTransferBuilder  │            │
│  ├──────────────────────┤  ├──────────────────────┤            │
│  │ • host()             │  │ • archive()          │            │
│  │ • user()             │  │ • verbose()          │            │
│  │ • port()             │  │ • compress()         │            │
│  │ • ssh_private_key_path()    │  │ • delete()           │            │
│  │ • timeout_secs()     │  │ • exclude()          │            │
│  │ • connect()          │  │ • push()             │            │
│  └──────────────────────┘  │ • pull()             │            │
│                              └──────────────────────┘            │
│  ┌──────────────────────┐                                       │
│  │ SshConnection Methods│                                       │
│  ├──────────────────────┤                                       │
│  │ • execute(cmd)       │                                       │
│  │ • ping()             │                                       │
│  │ • file_transfer()    │                                       │
│  └──────────────────────┘                                       │
└─────────────────────────────────────────────────────────────────┘
```

## Learning Path

1. Start with `03_ssh_builder_basics.rhai` - Quick start guide
2. Read `08_ssh_builder_pattern.rhai` - Comprehensive reference
3. Review `09_ssh_refactoring_guide.md` - Architecture details
