Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/cargo-deny.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Cargo Deny

on:
push:
branches: [ main ]
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
- 'deny.toml'
- '.github/workflows/cargo-deny.yml'
pull_request:
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
- 'deny.toml'
- '.github/workflows/cargo-deny.yml'
schedule:
- cron: '0 0 * * MON' # Weekly on Monday

jobs:
cargo-deny:
name: License and Security Check
runs-on: ubuntu-latest
strategy:
matrix:
checks:
- advisories
- bans licenses sources

# Prevent duplicate runs
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.checks }}
cancel-in-progress: true

steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install Rust
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a # stable
with:
toolchain: stable

- name: Install cargo-deny
uses: taiki-e/install-action@v2
with:
tool: cargo-deny@0.16.2

- name: Run cargo-deny
run: cargo deny --all-features check ${{ matrix.checks }}
23 changes: 15 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1

# Cancel previous runs of the same workflow
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true

jobs:
test:
name: Test
Expand All @@ -19,16 +24,16 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
rust: [stable]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a # stable
with:
toolchain: ${{ matrix.rust }}
components: rustfmt, clippy

- name: Cache cargo
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5

- name: Check formatting
run: cargo fmt --all -- --check
Expand All @@ -49,24 +54,26 @@ jobs:
name: Code Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a # stable
with:
toolchain: stable

- name: Cache cargo
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5

- name: Install tarpaulin
uses: taiki-e/install-action@v2
with:
tool: cargo-tarpaulin
tool: cargo-tarpaulin@0.31.2

- name: Generate coverage
run: cargo tarpaulin --workspace --all-features --out xml --timeout 300

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.1
with:
files: ./cobertura.xml
fail_ci_if_error: false
23 changes: 14 additions & 9 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,31 @@ on:
env:
CARGO_TERM_COLOR: always

# Cancel previous runs
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
security-audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a # stable

- name: Cache cargo registry
uses: Swatinem/rust-cache@v2
uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2.7.5
with:
cache-on-failure: true

- name: Install cargo-audit
uses: taiki-e/install-action@v2
with:
tool: cargo-audit
tool: cargo-audit@0.20.5

- name: Run security audit
run: cargo audit --deny warnings
Expand Down Expand Up @@ -67,7 +72,7 @@ print(json.dumps(sarif))

- name: Upload audit results to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v3
uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f2 # v3.27.4
with:
sarif_file: audit.sarif
category: dependency-audit
Expand All @@ -77,10 +82,10 @@ print(json.dumps(sarif))
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Run cargo-deny
uses: EmbarkStudios/cargo-deny-action@v2
uses: EmbarkStudios/cargo-deny-action@8371184bd11e21dcf8ac82ebf8c9c9f74ebf7268 # v2.0.3
with:
command: check
arguments: --all-features
Expand All @@ -92,10 +97,10 @@ print(json.dumps(sarif))
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Dependency Review
uses: actions/dependency-review-action@v4
uses: actions/dependency-review-action@a6993e2c61fd5dc440b409aa1d6904921c5e1894 # v5.0.0
with:
fail-on-severity: high
deny-licenses: GPL-3.0, AGPL-3.0
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,5 @@ make docker-down
- All public APIs must have doc comments
- Conventional commits: `feat:`, `fix:`, `docs:`, `test:`, `chore:`, etc.
- Feature branch workflow (never commit directly to main)
- No emoji in code, commits, or documentation
- No emoji in code, commits, or documentation
- always squash commits on a branch/pr
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ debug = true
[profile.dist]
inherits = "release"
lto = "thin"

74 changes: 61 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,32 @@ A unified command-line interface for managing Redis deployments across Cloud and

## Installation

### From crates.io (Recommended)
### CLI Tool (Recommended for most users)
```bash
# Install the latest version
# Install the CLI tool
cargo install redisctl
```

### Rust Libraries (For developers building custom tools)

# Or install specific library crates
cargo install redis-cloud
cargo install redis-enterprise
This project also provides **comprehensive Rust client libraries** for both Redis Cloud and Enterprise REST APIs:

```toml
# Add to your Cargo.toml
[dependencies]
redis-cloud = "0.1.0" # Full Redis Cloud REST API client
redis-enterprise = "0.1.0" # Full Redis Enterprise REST API client
```

These libraries offer:
- **100% API coverage** - Every documented endpoint implemented
- **Full type safety** - Strongly typed request/response structures
- **Async/await** - Modern async Rust with Tokio
- **Builder patterns** - Ergonomic client configuration
- **Comprehensive testing** - Battle-tested with 500+ tests

Perfect for building custom automation, integrations, or management tools.

### From Source
```bash
# Clone and build
Expand Down Expand Up @@ -284,7 +300,9 @@ See our [GitHub Issues](https://github.com/joshrotenberg/redisctl/issues) for th
- Terraform provider integration
- Kubernetes operator

## Using as a Library
## Rust Library Usage

For developers who want to build their own tools, our libraries provide complete, type-safe access to Redis Cloud and Enterprise APIs:

Add to your `Cargo.toml`:
```toml
Expand All @@ -293,29 +311,59 @@ redis-cloud = "0.1.0" # For Cloud API
redis-enterprise = "0.1.0" # For Enterprise API
```

Example usage:
### Quick Example
```rust
use redis_cloud::CloudClient;
use redis_enterprise::EnterpriseClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Cloud API
// Redis Cloud API client
let cloud = CloudClient::new("api_key", "api_secret")?;
let databases = cloud.database().list(123).await?;

// Enterprise API
// List all databases in a subscription
let databases = cloud.database().list(subscription_id).await?;

// Create a new database
let new_db = cloud.database()
.create(subscription_id, CreateDatabaseRequest {
name: "production-cache".to_string(),
memory_limit_in_gb: 10.0,
// ... other settings
})
.await?;

// Redis Enterprise API client
let enterprise = EnterpriseClient::builder()
.url("https://cluster:9443")
.username("admin")
.password("pass")
.username("admin@example.com")
.password("secure_password")
.insecure(false) // Set true for self-signed certs
.build()?;
let cluster_info = enterprise.cluster().get().await?;

// Get cluster information
let cluster = enterprise.cluster().get().await?;

// Create a database
let db = enterprise.database()
.create(CreateDatabaseRequest {
name: "mydb".to_string(),
memory_size: 1073741824, // 1GB in bytes
// ... other settings
})
.await?;

Ok(())
}
```

### Library Features
- **Comprehensive handlers** for all API endpoints (subscriptions, databases, users, ACLs, etc.)
- **Builder patterns** for complex request construction
- **Error handling** with detailed context and retry logic
- **Both typed and untyped** responses (use `.raw()` methods for `serde_json::Value`)
- **Extensive documentation** on [docs.rs](https://docs.rs/redis-cloud) and [docs.rs](https://docs.rs/redis-enterprise)

## Support

- **Issues**: [GitHub Issues](https://github.com/joshrotenberg/redisctl/issues)
Expand Down
5 changes: 5 additions & 0 deletions crates/redisctl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,8 @@ enterprise-only = ["enterprise"]
assert_cmd = "2.0"
predicates = "3.0"
tempfile = "3.8"
criterion = "0.5"

[[bench]]
name = "api_performance"
harness = false
Loading
Loading