# rc - Rust S3 CLI Client

[![CI](https://github.com/rustfs/cli/actions/workflows/ci.yml/badge.svg)](https://github.com/rustfs/cli/actions/workflows/ci.yml)
[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](LICENSE-APACHE)
[![Crates.io](https://img.shields.io/crates/v/rustfs-cli.svg)](https://crates.io/crates/rustfs-cli)
[![Docs.rs](https://docs.rs/rustfs-cli/badge.svg)](https://docs.rs/rustfs-cli)

A S3-compatible command-line client written in Rust.

## Features

- 🚀 **High Performance** - Written in Rust with async concurrent operations
- 🔧 **S3 Compatible** - Supports RustFS, MinIO, AWS S3, and other S3-compatible services
- 📦 **Cross-Platform** - Supports Linux, macOS, and Windows
- 🎨 **Friendly Output** - Human-readable and JSON format output
- 🔒 **Secure** - Secure credential storage, no sensitive data in logs

## Installation

### Binary Download

Download the appropriate binary for your platform from the [Releases](https://github.com/rustfs/cli/releases) page.
On Linux, use the default `linux-amd64` / `linux-arm64` artifacts for maximum compatibility (`musl` static build).
If you specifically need glibc-linked builds, use `linux-amd64-gnu` / `linux-arm64-gnu`.

### Homebrew (macOS/Linux)

```bash
brew install rustfs/tap/rc
```

### Scoop (Windows)

```powershell
scoop bucket add rustfs https://github.com/rustfs/scoop-bucket
scoop install rustfs/rc
```

### Cargo

```bash
cargo install rustfs-cli
```

### Docker

```bash
# Show help
docker run --rm rustfs/rc:latest --help

# Run a command with a local RustFS instance
docker run --rm --network host rustfs/rc:latest \
  alias set local http://localhost:9000 accesskey secretkey
```

### Build from Source

```bash
git clone https://github.com/rustfs/cli.git
cd cli
cargo build --release
```

## Quick Start

### Configure Aliases

```bash
# Add local S3 service
rc alias set local http://localhost:9000 accesskey secretkey

# Add AWS S3
rc alias set s3 https://s3.amazonaws.com AKIAIOSFODNN7EXAMPLE wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

# List all aliases
rc alias list
```

### Basic Operations

```bash
# List buckets
rc ls local/

# Create bucket
rc mb local/my-bucket

# Upload file
rc cp ./file.txt local/my-bucket/

# Download file
rc cp local/my-bucket/file.txt ./

# View object info
rc stat local/my-bucket/file.txt

# Delete object
rc rm local/my-bucket/file.txt

# Delete bucket
rc rb local/my-bucket
```

### Advanced Operations

```bash
# Recursively copy directory
rc cp -r ./local-dir/ local/bucket/remote-dir/

# Mirror between S3 locations
rc mirror local/bucket1/ local/bucket2/

# Find objects
rc find local/bucket --name "*.txt" --newer 1d

# List anonymous access rules
rc anonymous list local/bucket

# Set anonymous access level
rc anonymous set public local/bucket/public

# Generate download link
rc share download local/bucket/file.txt --expire 24h

# View directory tree
rc tree local/bucket -L 3
```

### Admin Operations (IAM)

```bash
# List users
rc admin user list local/

# Add a new user
rc admin user add local/ newuser secretpassword

# Create a policy
rc admin policy create local/ readonly --file policy.json

# Attach policy to user
rc admin policy attach local/ readonly --user newuser

# Create a service account (access_key + secret_key)
rc admin service-account create local/ AKIAIOSFODNN7EXAMPLE wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

# Create a service account with inline policy file
rc admin service-account create local/ SAKEY123 SASECRET123 --policy ./service-account-policy.json

# Manage bucket event notifications
rc event add local/my-bucket arn:aws:sns:us-east-1:123456789012:topic --event 's3:ObjectCreated:*'
rc event list local/my-bucket
rc event remove local/my-bucket arn:aws:sns:us-east-1:123456789012:topic

# Manage bucket CORS configuration
rc bucket cors list local/my-bucket
rc bucket cors get local/my-bucket
rc bucket cors set local/my-bucket cors.xml
cat cors.xml | rc bucket cors set local/my-bucket -
rc bucket cors set local/my-bucket --file cors.json
rc cors remove local/my-bucket
```

### Lifecycle (ILM) Operations

```bash
# Add lifecycle rule: expire objects after 30 days with prefix filter
rc ilm rule add local/my-bucket --expiry-days 30 --prefix "logs/"

# Add lifecycle rule: transition to remote tier after 90 days
rc ilm rule add local/my-bucket --transition-days 90 --storage-class WARM

# List lifecycle rules
rc ilm rule list local/my-bucket

# Edit an existing rule
rc ilm rule edit local/my-bucket --id rule-abc123 --expiry-days 60

# Remove a specific rule or all rules
rc ilm rule remove local/my-bucket --id rule-abc123
rc ilm rule remove local/my-bucket --all

# Export/import lifecycle configuration (JSON)
rc ilm rule export local/my-bucket > lifecycle.json
rc ilm rule import local/my-bucket lifecycle.json

# Manage remote storage tiers
rc ilm tier add rustfs WARM local --endpoint http://remote:9000 --access-key ak --secret-key sk --bucket warm-bucket
rc ilm tier list local
rc ilm tier info WARM local
rc ilm tier remove WARM local --force

# Restore a transitioned (archived) object
rc ilm restore local/my-bucket/archived-file.dat --days 7
```

### Bucket Replication

```bash
# Replication requires versioning on both source and destination buckets
rc version enable local/my-bucket
rc version enable remote/target-bucket

# Configure a remote alias with the destination RustFS endpoint URL.
# rc normalizes the remote target endpoint to the host:port form expected by
# the RustFS admin API when creating replication targets.
rc alias set remote http://remote:9000 ACCESS_KEY SECRET_KEY

# Add a replication rule
rc replicate add local/my-bucket \
  --remote-bucket remote/target-bucket \
  --priority 1 \
  --replicate delete,delete-marker,existing-objects

# List replication rules
rc replicate list local/my-bucket

# View replication status/metrics
rc replicate status local/my-bucket

# Update a replication rule
rc replicate update local/my-bucket --id rule-1 --priority 2

# Remove replication rules
rc replicate remove local/my-bucket --id rule-1
rc replicate remove local/my-bucket --all

# Export/import replication configuration (JSON)
rc replicate export local/my-bucket > replication.json
rc replicate import local/my-bucket replication.json
```

### Admin Operations (Cluster)

```bash
# Cluster information
rc admin info cluster local
rc admin info server local
rc admin info disk local --offline

# Heal operations
rc admin heal status local
rc admin heal start local --bucket mybucket --scan-mode deep
rc admin heal start local --dry-run
rc admin heal stop local

# Pool expansion and decommission workflows
rc admin pool list local
rc admin pool status local 1 --by-id
rc admin expand start local
rc admin expand status local
rc admin expand stop local
rc admin decommission start local '/data/pool1/disk{1...4}'
rc admin decommission status local '/data/pool1/disk{1...4}'
rc admin decommission cancel local 1 --by-id

# Rebalance data after adding server pools
rc admin rebalance start local
rc admin rebalance status local
rc admin rebalance stop local

# JSON output
rc admin info cluster local --json
rc admin heal status local --json
rc admin rebalance status local --json
```

## Command Overview

| Command       | Description                                                                  |
|---------------|------------------------------------------------------------------------------|
| `alias`       | Manage storage service aliases                                               |
| `admin`       | Manage IAM users, policies, groups, service accounts, and cluster operations |
| `ls`          | List buckets or objects                                                      |
| `mb`          | Make bucket                                                                  |
| `rb`          | Remove bucket                                                                |
| `cp`          | Copy objects                                                                 |
| `mv`          | Move objects                                                                 |
| `rm`          | Remove objects                                                               |
| `cat`         | Display object contents                                                      |
| `head`        | Display first N lines of object                                              |
| `stat`        | Display object metadata                                                      |
| `find`        | Find objects                                                                 |
| `anonymous`   | Manage anonymous access to buckets and objects                               |
| `diff`        | Compare two locations                                                        |
| `mirror`      | Mirror sync between S3 locations                                             |
| `tree`        | Tree view display                                                            |
| `share`       | Generate presigned URLs                                                      |
| `event`       | Manage bucket event notifications                                            |
| `cors`        | Manage bucket CORS configuration                                             |
| `pipe`        | Upload from stdin                                                            |
| `version`     | Manage bucket versioning                                                     |
| `tag`         | Manage bucket and object tags                                                |
| `quota`       | Manage bucket quota                                                          |
| `ilm`         | Manage lifecycle rules, storage tiers, and object restore                    |
| `replicate`   | Manage bucket replication                                                    |
| `completions` | Generate shell completion scripts                                            |

### Admin Subcommands

| Command                 | Description                                                                           |
|-------------------------|---------------------------------------------------------------------------------------|
| `admin user`            | Manage IAM users (add, remove, list, info, enable, disable)                           |
| `admin policy`          | Manage IAM policies (create, remove, list, info, attach)                              |
| `admin group`           | Manage IAM groups (add, remove, list, info, enable, disable, add-members, rm-members) |
| `admin service-account` | Manage service accounts (create, remove, list, info)                                  |
| `admin info`            | Display cluster information (cluster, server, disk)                                   |
| `admin heal`            | Manage cluster healing operations (status, start, stop)                               |
| `admin pool`            | List pools and inspect expansion/decommission status                                  |
| `admin expand`          | Manage post-expansion data rebalancing (start, status, stop)                          |
| `admin decommission`    | Manage server pool decommissioning (start, status, cancel)                            |
| `admin rebalance`       | Manage post-expansion rebalancing (start, status, stop)                               |

### ILM Subcommands

| Command           | Description                              |
|-------------------|------------------------------------------|
| `ilm rule add`    | Add a lifecycle rule to a bucket         |
| `ilm rule edit`   | Edit an existing lifecycle rule          |
| `ilm rule list`   | List lifecycle rules on a bucket         |
| `ilm rule remove` | Remove lifecycle rules from a bucket     |
| `ilm rule export` | Export lifecycle configuration as JSON   |
| `ilm rule import` | Import lifecycle configuration from JSON |
| `ilm tier add`    | Add a remote storage tier                |
| `ilm tier edit`   | Edit tier credentials                    |
| `ilm tier list`   | List all configured storage tiers        |
| `ilm tier info`   | Show details for a specific tier         |
| `ilm tier remove` | Remove a storage tier                    |
| `ilm restore`     | Restore a transitioned (archived) object |

### Replicate Subcommands

| Command            | Description                                |
|--------------------|--------------------------------------------|
| `replicate add`    | Add a new replication rule                 |
| `replicate update` | Update an existing replication rule        |
| `replicate list`   | List replication rules for a bucket        |
| `replicate status` | Show replication status and metrics        |
| `replicate remove` | Remove replication rules                   |
| `replicate export` | Export replication configuration as JSON   |
| `replicate import` | Import replication configuration from JSON |

## Output Format

### Human-Readable (default)

```bash
rc ls local/bucket
[2024-01-15 10:30:00]     0B dir/
[2024-01-15 10:30:00] 1.2MiB file.txt
```

### JSON Format

```bash
rc ls local/bucket --json
```

```json
{
  "items": [
    {
      "key": "dir/",
      "is_dir": true
    },
    {
      "key": "file.txt",
      "size_bytes": 1258291,
      "size_human": "1.2 MiB",
      "is_dir": false
    }
  ],
  "truncated": false
}
```

## Shell Completion

Generate and install shell completion scripts:

### Bash

```bash
rc completions bash > ~/.bash_completion.d/rc
# Or add to .bashrc:
# source <(rc completions bash)
```

### Zsh

```bash
rc completions zsh > ~/.zfunc/_rc
# Ensure ~/.zfunc is in your fpath (add to .zshrc):
# fpath=(~/.zfunc $fpath)
# autoload -Uz compinit && compinit
```

### Fish

```bash
rc completions fish > ~/.config/fish/completions/rc.fish
```

### PowerShell

```powershell
rc completions powershell >> $PROFILE
```

## Configuration

Configuration file is located at `~/.config/rc/config.toml`:

```toml
schema_version = 1

[defaults]
output = "human"
color = "auto"
progress = true

[[aliases]]
name = "local"
endpoint = "http://localhost:9000"
access_key = "accesskey"
secret_key = "secretkey"
region = "us-east-1"
```

## Exit Codes

| Code | Description                     |
|------|---------------------------------|
| 0    | Success                         |
| 1    | General error                   |
| 2    | Usage/path error                |
| 3    | Network error (retryable)       |
| 4    | Authentication/permission error |
| 5    | Resource not found              |
| 6    | Conflict/precondition failed    |
| 7    | Feature not supported           |
| 130  | Interrupted (Ctrl+C)            |

## Compatibility

### Supported Backends

| Backend             | Tier        | Description         |
|---------------------|-------------|---------------------|
| RustFS              | Tier 1      | Fully supported     |
| MinIO               | Tier 2      | Fully supported     |
| AWS S3              | Tier 3      | Best effort support |
| Other S3-compatible | Best Effort | No guarantee        |

### Minimum Rust Version

- Rust 1.92 or higher (Edition 2024)

## Development

### Build

```bash
cargo build --workspace
```

### Test

```bash
# Unit tests
cargo test --workspace

# Integration tests (requires S3-compatible backend)
docker compose -f docker/docker-compose.yml up -d
cargo test --workspace --features integration
docker compose -f docker/docker-compose.yml down
```

### Lint

```bash
cargo fmt --all --check
cargo clippy --workspace -- -D warnings
```

## Contributing

Contributions are welcome! Please read [AGENTS.md](AGENTS.md) for development guidelines.

## License

This project is dual-licensed under MIT or Apache-2.0. See [LICENSE-MIT](LICENSE-MIT)
and [LICENSE-APACHE](LICENSE-APACHE).

## Acknowledgments

- [MinIO Client (mc)](https://github.com/minio/mc) - Inspiration for CLI design
- [aws-sdk-s3](https://crates.io/crates/aws-sdk-s3) - AWS S3 SDK for Rust
