Skip to main content

QUADS Client is an interactive TUI (Text User Interface) shell for managing multiple QUADS server instances.

Project description

quads-client

pytest codecov PyPI version Python 3.13+ License: GPL v3 Code style: black

QUADS Client is an interactive TUI (Text User Interface) shell for managing multiple QUADS server instances.

Features

  • Multi-Server Support: Connect to and manage multiple QUADS servers from a single interface
  • Session Management: Maintain multiple authenticated connections simultaneously and switch between them instantly
  • Bearer Token Authentication: Secure JWT-based authentication via python-quads-lib
  • Interactive Shell: Built on cmd2 with command history and comprehensive tab completion
  • Intelligent Tab Completion: Context-aware autocompletion for all commands, arguments, cloud names, hostnames, assignment IDs, and server names
  • Rich UI: Beautiful terminal output with colors, tables, and status indicators powered by python-rich
  • User Registration: Non-admin users can register accounts and manage their own assignments
  • Command History: SQLite-based persistent command history per server
  • Progress Tracking: Real-time provisioning progress monitoring
  • Connection Management: Easy switching between QUADS server instances
  • Thin Wrapper Design: Server-side authorization via QUADS API

QUADS Client Screenshot 1

QUADS Client Screenshot 2

QUADS Client Screenshot 3

Table of Contents

Installation

From PyPI (pip)

  • For Linux and Mac (with Python setup)
  • Install the latest stable release from PyPI:
python3 -m venv venv
source venv/bin/activate
pip install quads-client
  • Run QUADS Client
quads-client
  • To upgrade to the latest version:
source venv/bin/activate
pip install --upgrade quads-client
  • To deactivate the virtual environment when done:
deactivate

From RPM

For Red Hat-based distributions (RHEL, Rocky, Fedora):

dnf copr enable quadsdev/python3-quads -y
dnf install quads-client

From Source

For development or the latest unreleased features:

git clone https://github.com/quadsproject/quads-client.git
cd quads-client
python3 -m venv venv
source venv/bin/activate
pip install -e .

Configuration

Configuration File Location

Operating System Config File Location Notes
Linux ~/.config/quads/quads-client.yml Follows XDG Base Directory spec; directory auto-created on first run
macOS ~/.config/quads/quads-client.yml Standard CLI tool convention; directory auto-created on first run
Windows ~/.config/quads/quads-client.yml Expands to %USERPROFILE%\.config\quads\quads-client.yml
FreeBSD ~/.config/quads/quads-client.yml Follows XDG Base Directory spec; directory auto-created on first run

Quick Setup (Recommended)

[!TIP] The add-quads-server command creates the configuration file interactively. This is the easiest way to get started.

Use the interactive add-quads-server command:

quads-client
add-quads-server
# Follow the prompts to add your QUADS server
config-reload
connect <server_name>
register your.email@example.com YourPassword123

Manual Configuration (Advanced)

Alternatively, manually create the configuration file using the provided example configuration as a template.

Configuration Notes:

  • For new users: Leave username and password blank. Use the register command after connecting.
  • For existing users: Fill in credentials to login automatically on connect.
  • Specify the base URL only (no /api/v3/ path, no port :5000). The client automatically appends the API path.
  • verify: true enables SSL certificate verification (recommended). Set to false only for development/testing with self-signed certificates.

SSL/TLS Security Indicator

The client displays a visual security indicator in the prompt showing the SSL/TLS status of your connection:

Indicator Color Meaning
Green HTTPS with SSL certificate verification (trusted CA)
! Green HTTPS without SSL certificate verification (self-signed or verification disabled)
Yellow HTTP (no encryption)

Example prompts:

✓ (quads-prod.example.com) >   ← Secure HTTPS with verified certificate
! (quads-dev.example.com) >    ← HTTPS with self-signed certificate
✗ (quads-test.local) >         ← Insecure HTTP connection

[!WARNING] Using verify: false or HTTP connections exposes your credentials and data to potential interception. For production use, always configure your QUADS server with valid SSL/TLS certificates.

Setting up SSL/TLS on your QUADS server:
See the QUADS SSL configuration guide for instructions on configuring nginx with SSL certificates.

Usage

Interactive Mode

Launch the interactive shell:

quads-client

One-Shot Commands

Execute a single command and exit without entering interactive mode. The client automatically connects to your default server (configured in quads-client.yml) and returns proper exit codes for scripting.

Basic Commands (no connection required):

quads-client version                # Show client version
quads-client help                   # Show available commands
quads-client servers                # List configured servers

Auto-Connect Commands:

One-shot commands requiring a connection will automatically connect to your default server (set default_server in ~/.config/quads/quads-client.yml).

# View resources (uses default server)
quads-client cloud_list             # List all clouds
quads-client my_hosts               # Show your scheduled hosts
quads-client my_assignments         # List your assignments

# Check available hosts
quads-client ls_available model r650 ram 256
quads-client ls_available start 2026-06-01 end 2026-06-15

Specify Non-Default Server:

To run a one-shot command against a non-default server, use connect <server> <command>:

# Connect to specific server and run command
quads-client connect quads-prod my_assignments
quads-client connect quads-stage cloud_list
quads-client connect quads-dev.dc1.example.com available

# Works with fuzzy server matching (FQDN, short names)
quads-client connect quads-stage.dc2.example.com ls_available

Self-Schedule (SSM Mode):

Quick one-shot scheduling for regular users:

# Schedule hosts by count (QUADS picks hosts automatically)
quads-client schedule 3 description "dev testing"
quads-client schedule 5 description "perf lab" model r640 ram 128

# Schedule specific hosts
quads-client schedule host01.example.com,host02.example.com description "CI pipeline"

# Schedule from host list file
quads-client schedule host-list ~/hosts.txt description "batch test"

# Terminate assignment when done
quads-client terminate 42

Admin Operations:

# Extend schedules
quads-client extend cloud05 weeks 2
quads-client extend cloud17 date "2026-06-15 22:00"
quads-client extend host01.example.com weeks 1

# Create schedules
quads-client schedule cloud02 host01.example.com,host02.example.com 2026-05-15 2026-06-15
quads-client schedule cloud17 host-list ~/hosts.txt now 2026-07-01

# Shrink schedules
quads-client shrink host01.example.com weeks 2

Exit Codes:

One-shot commands return standard exit codes for scripting:

  • 0 - Success
  • 1 - Command error (validation, API error)
  • 3 - Connection error (no default server, connection failed)
  • 130 - Interrupted (Ctrl+C)

Scripting Example:

#!/bin/bash
# Check if hosts are available before scheduling
if quads-client ls_available model r650 ram 256 > /dev/null 2>&1; then
    quads-client schedule 3 description "CI job ${BUILD_ID}" model r650 ram 256
    echo "Scheduled hosts successfully"
else
    echo "No hosts available matching criteria"
    exit 1
fi

Tips:

  • Set default_server in your config to enable auto-connect
  • One-shot commands suppress banner and connection messages for clean output
  • Use > /dev/null 2>&1 to suppress all output in scripts
  • Commands use underscores (e.g., cloud_list, my_hosts)
  • All table output goes to stdout for easy parsing

How to Self-Schedule

Quick start for regular users:

# 1. Connect and register
quads-client
connect quads-prod.example.com
register your.email@example.com YourPassword123

# 2. Schedule hosts (automatic for 5 days or until Sunday 21:00 UTC)
schedule 3 description "My dev environment"
schedule host01,host02 description "CI testing"
schedule host-list hosts.txt description "Perf lab"

# 3. Check your hosts
my-hosts
my-assignments

# 4. Release when done
terminate 42                    # Terminate entire assignment
terminate 42 host01.example.com # Release single host

That's it. No tickets, no admin approval required.

Commands

Tab Completion

QUADS Client provides comprehensive tab completion for all commands and their arguments:

Command Completion: Press Tab after typing partial command names

(quads1-dev) > clo<Tab>
cloud-create  cloud-delete  cloud-list

Context-Aware Argument Completion: Press Tab to complete command arguments based on live server data

  • Cloud names: cloud-delete <Tab> → shows available clouds
  • Hostnames: mark-broken <Tab> → shows non-broken hosts
  • Assignment IDs: terminate <Tab> → shows your active assignment IDs
  • Server names: connect <Tab> → shows configured servers
  • Keywords: schedule <Tab> → shows options like description, nowipe, vlan, qinq, model, ram

Examples:

# SSM mode - schedule command shows hostnames first, then keywords
(quads1-dev) > schedule <Tab>
host01.example.com  host02.example.com  host03.example.com  1  2  3  5  10

(quads1-dev) > schedule 3 <Tab>
description  nowipe  vlan  qinq  model  ram  host-list

# Admin mode - schedule command shows cloud names first
(quads1-dev) > schedule <Tab>
cloud01  cloud02  cloud03

# Cloud operations
(quads1-dev) > cloud-list cloud <Tab>
cloud01  cloud02  cloud03

# Terminate command
(quads1-dev) > terminate <Tab>
42  43  44

# Host management
(quads1-dev) > mark-broken <Tab>
host01.example.com  host02.example.com  host03.example.com

Tab completion dynamically fetches data from the connected QUADS server, ensuring you always see up-to-date options.

Connection Management

connect quads1.example.com                   - Connect to a QUADS server by name
connect 2                                    - Connect by server number from 'servers' list
connect quads-prod session prod              - Create a labeled session
disconnect                                   - Disconnect from current server
status                                       - Show connection status and active sessions

Examples:

connect quads1.example.com  # Connect by server name
connect 2                   # Connect by server number from 'servers' list
connect quads-prod session prod  # Create a labeled session

Fuzzy Server Name Matching:

The connect command supports flexible server name matching for convenience:

# Config has: "quads-dev.dc1" with URL "https://quads-dev.dc1.example.com"

connect quads-dev.dc1                    # Exact match (config key)
connect quads-dev.dc1.example.com        # FQDN match (from URL)
connect https://quads-dev.dc1.example.com # Full URL match

The client will intelligently resolve:

  1. Exact match - Matches config keys exactly
  2. URL matching - Strips https:// and trailing slashes to match server URLs
  3. Prefix matching - If unique, matches shortened names (e.g., quads-prod)

This allows you to connect using the FQDN even if your config uses a shortened alias.

Multi-Server Session Management

QUADS Client allows you to maintain multiple authenticated connections simultaneously. This is useful when working across multiple environments (dev, staging, production) or comparing data between servers.

Key Benefits:

  • No re-authentication: Sessions stay authenticated when you switch between them
  • Instant switching: Move between servers without reconnecting
  • Labeled sessions: Use memorable names instead of full server hostnames
  • Session visibility: See all active connections at a glance

Session Commands:

session-create quads-prod label prod      - Create new session with optional label
session prod                              - Quick switch to session by ID or label  
session-switch 2                          - Switch to session by ID
session-list                              - Show all active sessions with status
session-close 2                           - Close specific session
session-close-all                         - Close all inactive sessions

Quick Start Example:

# Connect to multiple servers with labels
> connect quads-prod.example.com session prod
OK: Connected to quads-prod.example.com as user@example.com (session 1)

> connect quads-dev.example.com session dev
OK: Connected to quads-dev.example.com as user@example.com (session 2)

# Prompt shows active sessions: [1:prod 2:dev*] [1:prod 2:dev*] (quads-dev) >

# Quick switch between environments
> session prod
Switched to session 1 (prod) [1:prod* 2:dev] (quads-prod) > cloud-list
[shows production clouds]

> session dev
Switched to session 1 (dev) [1:prod 2:dev*] (quads-dev) >

# View all sessions
> session-list
┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Session   Server                    Label    Version  Status        Last Active  ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ 1         quads-prod.example.com    prod     2.2.6     Idle        2m ago       │
│ 2         quads-dev.example.com     dev      2.2.6     Active     now          │
└──────────┴──────────────────────────┴─────────┴─────────┴──────────────┴──────────────┘

Session Indicators in Prompt:

When you have multiple sessions, the prompt displays them for quick reference:

✓ [1:prod 2:dev* 3:stage] (quads-dev) >
   │       │       └─ Asterisk marks active session
   │       └───────── Session IDs with labels
   └─────────────────── SSL status indicator

Common Workflows:

Compare environments:

> connect quads-prod session prod
> connect quads-dev session dev
> session prod
> cloud-list cloud cloud05 detail  # Check prod state
> session dev  
> cloud-list cloud cloud05 detail  # Compare with dev

Work in dev, monitor prod:

> connect quads-dev session dev
> connect quads-prod session prod
> session dev
> schedule 3 description "Testing new feature"
> session prod  # Quick check on production
> my-hosts      # Verify prod assignments
> session dev   # Back to development work

Tips:

  • Sessions remain authenticated even when inactive
  • Use session-close-all to clean up when switching projects
  • The status command shows all sessions when you have multiple connections
  • Configuration changes with config-reload update all active sessions

Server Management

servers              - List all configured servers with status
add-quads-server     - Interactive wizard to add a new QUADS server
add-server quads3 https://quads3.example.com user@example.com password123 [noverify]  
                     - Add new server to configuration (advanced)
edit-server quads3 [url https://new.example.com] [username newuser@example.com] 
                   [password newpass] [verify true|false]
                     - Edit existing server configuration
rm-server quads3     - Remove server from configuration
config-reload        - Reload configuration from file

Adding a server (interactive method):

add-quads-server
# Follow the prompts:
#   1. Enter server name (e.g., quads1.example.com)
#   2. Enter server URL (e.g., https://quads1.example.com)
#   3. Enable SSL verification? [Y/n]
# Then: config-reload, connect, and register

Cloud Management

cloud-list                                         - List all clouds
cloud-list cloud cloud05 detail                    - Show detailed cloud info with hosts
cloud-create cloud10                               - Create a new cloud (admin only)
cloud-delete cloud10                               - Delete a cloud (admin only)
mod-cloud cloud02 [OPTIONS]                        - Modify cloud attributes (admin only)
  owner alice@example.com                          - Set cloud owner
  description "Production environment"             - Set cloud description
  ticket JIRA-12345                                - Set ticket number
  wipe true|false                                  - Enable/disable wipe
  ccusers "alice@example.com,bob@example.com"      - Set CC users list

Self-Scheduling Mode (SSM)

Self-Scheduling Mode allows regular (non-admin) users to schedule hosts without admin intervention. The QUADS server automatically creates assignments and clouds - no tickets required.

register <email> <password>                      - Register a new user
login                                            - Explicit login
whoami                                           - Show current user information
schedule <count|hostname[,hostname...]|host-list path> description <desc> [OPTIONS]
                                                 - Schedule hosts (SSM mode)
  nowipe                                         - Disable wipe (default: wipe enabled)
  vlan <id>                                      - VLAN ID
  qinq <0|1>                                     - QinQ mode
  model <model>                                  - Filter by model (count mode only)
  ram <GB>                                       - Minimum RAM in GB (count mode only)
my-assignments                                   - List all your assignments
my-hosts                                         - Show your currently scheduled hosts
available                                        - Show available hosts for self-scheduling
terminate <assignment-id> [hostname]             - Terminate assignment or release host

SSM Syntax:

# MODE 1: Count - just specify a NUMBER (QUADS picks hosts for you)
schedule 3 description "Dev testing"
schedule 5 description "Perf lab" model r640 ram 128  # With filters

# MODE 2: Specific hosts - comma-separated hostnames (NO SPACES!)
schedule host01.example.com,host02.example.com description "CI pipeline"

# MODE 3: Host list file - one hostname per line
schedule host-list ~/hosts.txt description "Batch test" vlan 1150 nowipe

# View and manage assignments
my-assignments
my-hosts
terminate 42
terminate 42 host03.example.com

Common Mistakes:

# ❌ WRONG - "hosts" is not a keyword!
schedule hosts 3 description "test"

# ✅ CORRECT - just the number
schedule 3 description "test"

SSM Server Requirements:

  • QUADS server must have self_serve_enabled: true in quads.yml
  • No ticketing system required for SSM mode
  • Server limits: max 10 hosts per assignment, max 3 active assignments per user
  • Auto-expiration: 5 days or Sunday 21:00 UTC (configurable server-side)

Host Management (Admin)

ls-hosts                         - List all hosts
mark-broken host01.example.com   - Mark a host as broken
mark-repaired host01.example.com - Mark a broken host as repaired
retire host01.example.com        - Mark a host as retired
unretire host01.example.com      - Mark a retired host as active
ls-broken                        - List all broken hosts
ls-retired                       - List all retired hosts

Schedule Management (Admin)

schedule cloud02 host01,host02 "2026-05-15" "2026-06-15"  - Schedule hosts (admin mode)
schedule cloud17 host-list ~/hosts.txt now "2026-07-01"   - Schedule with host list file
ls-schedule [host host01.example.com] [cloud cloud02]     - List schedules
mod-schedule id 123 [start "2026-05-15"] [end "2026-06-15"] - Modify schedule dates
rm-schedule 123                                             - Remove a schedule
extend cloud02 weeks 2                                      - Extend cloud by weeks
extend cloud02 date "2026-05-17 22:00"                      - Extend cloud to specific date
extend host01.example.com weeks 1                           - Extend single host
shrink host01.example.com weeks 2                           - Shrink schedule by weeks

Admin Examples:

schedule cloud02 host01,host02,host03 2026-05-11 2026-06-11
schedule cloud17 host-list ~/hosts.txt now 2026-07-01
extend cloud02 weeks 2
extend cloud02 date "2026-05-17 22:00"
extend host01.example.com weeks 1

Available Hosts

ls-available [OPTIONS]
  start YYYY-MM-DD        - Start date for availability
  end YYYY-MM-DD          - End date for availability
  model MODEL             - Filter by server model
  ram GB                  - Minimum RAM in GB
  gpu-vendor VENDOR       - GPU vendor (e.g., "NVIDIA Corporation")
  gpu-product PRODUCT     - GPU model (e.g., "Tesla V100")
  disk-size GB            - Minimum disk size in GB
  disk-type TYPE          - Disk type (nvme, ssd, sata)
  disk-count N            - Minimum number of disks
  interfaces N            - Minimum number of network interfaces

Examples:

ls-available model r640 ram 256
ls-available gpu-vendor "NVIDIA Corporation" gpu-product "Tesla V100"
ls-available disk-type nvme disk-count 2 interfaces 4
ls-available start 2026-06-01 end 2026-06-15 model r650

Other Commands

version             - Show quads-client version
help [command]      - Show help for command(s)
exit / quit         - Exit the shell

Authorization

quads-client is a thin wrapper around the QUADS API via python-quads-lib. All authorization is handled server-side by the QUADS server.

Server Roles

The QUADS server implements two roles:

  • admin: Full access to create/delete clouds, manage all schedules, and perform administrative operations
  • user: Can view and filter available resources; limited to self-scheduling for creating assignments

When a command requires elevated permissions, the server will return a 403 Forbidden error, which quads-client displays to the user.

User Registration & Assignments

Users can register accounts directly from the CLI:

  1. Connect to a server (credentials can be blank in config)
  2. Register with register <email> <password>
  3. Credentials are automatically saved to your config file
  4. Login with the login command or reconnect

SSM users can:

  • Schedule hosts with unified schedule command (count/hosts/host-list syntax)
  • View their own resources with my-assignments and my-hosts (ownership enforced)
  • Terminate assignments when done with terminate (own assignments only)
  • Duration: Server-controlled (5 days or Sunday 21:00 UTC, whichever first)
  • Limits: Max 10 hosts per assignment, max 3 active assignments per user

Command visibility:

  • SSM users see only allowed commands (no extend, no admin commands)
  • Admin users see all commands

The server controls which hosts can be self-scheduled via the can_self_schedule flag.

See docs/INTEGRATION_ANALYSIS.md for complete API integration details.

Architecture

quads-client/
├── src/quads_client/
│   ├── shell.py              - Main cmd2 shell
│   ├── config.py             - YAML configuration loader
│   ├── connection.py         - Server connection manager
│   ├── session_manager.py    - Multi-session management
│   ├── error_handler.py      - Error handling and auth retry
│   ├── arg_parser.py         - Command argument parsing
│   ├── history.py            - SQLite command history
│   ├── progress.py           - Provisioning progress tracker
│   ├── rich_console.py       - Rich terminal UI
│   ├── utils.py              - Shared utility functions (DRY helpers)
│   ├── auth.py               - Authentication utilities
│   ├── cli/
│   │   ├── __init__.py
│   │   └── main.py           - CLI entry point
│   └── commands/             - Command modules
│       ├── __init__.py
│       ├── available.py      - Available hosts
│       ├── cloud.py          - Cloud management
│       ├── connection.py     - Connection commands
│       ├── host.py           - Host management (admin)
│       ├── schedule.py       - Schedule management (admin)
│       ├── server.py         - Server configuration
│       ├── session.py        - Session management
│       ├── user.py           - User registration & self-scheduling
│       └── version.py        - Version command
├── conf/
│   └── quads-client.yml.example - Example configuration
├── tests/                    - pytest test suite (511 tests, 75.6% coverage)
├── rpm/
│   └── quads-client.spec     - RPM package specification
├── images/                   - Screenshots and documentation images
├── setup.py                  - Package setup configuration
├── pyproject.toml            - Modern Python project metadata
├── requirements.txt          - Production dependencies
├── requirements-dev.txt      - Development dependencies
└── pytest.ini                - pytest configuration

Dependencies

  • Python >= 3.13
  • cmd2 >= 2.0.0
  • quads-lib >= 0.1.9
  • PyYAML >= 6.0.0
  • argcomplete >= 3.1.2
  • tabulate >= 0.9.0
  • rich >= 13.0.0 (for enhanced terminal UI)

Development

Building from Source

python3 setup.py sdist

Building RPM

rpmbuild -bb rpm/quads-client.spec \
  --define "_sourcedir $(pwd)/dist" \
  --define "_builddir $(pwd)/build" \
  --define "_rpmdir $(pwd)/rpms"

Code Formatting

black --line-length 119 src/quads_client/

Testing

Run Tests

pytest tests/ -v

Run Tests with Coverage

pytest tests/ --cov=quads_client --cov-report=html --cov-report=term

Manual Testing

PYTHONPATH=src python3 -c "from quads_client.shell import QuadsClientShell; shell = QuadsClientShell(); shell.cmdloop()"

Contributing

See CONTRIBUTING.md for guidelines on how to contribute to this project.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quads_client-0.3.2.tar.gz (121.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

quads_client-0.3.2-py3-none-any.whl (77.0 kB view details)

Uploaded Python 3

File details

Details for the file quads_client-0.3.2.tar.gz.

File metadata

  • Download URL: quads_client-0.3.2.tar.gz
  • Upload date:
  • Size: 121.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for quads_client-0.3.2.tar.gz
Algorithm Hash digest
SHA256 67ec2bfe58c405a6ee142e9d6084081ca464b0c9c72f3ce593f7cc7cf5e8efbe
MD5 3b301339557a3e8fd909c0b8a8e9cc1a
BLAKE2b-256 7606ec0e6c7ff1212fde48541daefabd6cd051dbf5678a86dadb2012ad2c516a

See more details on using hashes here.

File details

Details for the file quads_client-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: quads_client-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 77.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for quads_client-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 17d9a7e6c9b004779b7aa8ccf6d6f593ccdf9e1cbfc7b95be1ad6d6e2883b118
MD5 c802bbf35c65617656e157730ba904c3
BLAKE2b-256 ad467d6e55d70e340f9b26f3bc00ab0726975eb1644d97c3a04925b456da9593

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page