# Isard CLI

[![PyPI version](https://badge.fury.io/py/isard.svg)](https://badge.fury.io/py/isard)
[![Python 3.14+](https://img.shields.io/badge/python-3.14+-blue.svg)](https://www.python.org/downloads/)
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
[![Pipeline Status](https://gitlab.com/daviddemingo/isard/badges/main/pipeline.svg)](https://gitlab.com/daviddemingo/isard/-/pipelines)

A Python CLI tool for managing IsardVDI virtual desktops on the Gencat educational platform (`elmeuescriptori.gestioeducativa.gencat.cat`). This tool provides a streamlined command-line interface for educators and administrators to manage virtual desktop environments.

## Features

- **Seamless Authentication**: Automated SAML 2.0 flow via Azure Entra ID with session caching
- **Desktop Management**: Create, start, stop, delete, and list virtual desktops with detailed status information
- **Template Management**: Browse and select from available desktop templates with hardware specifications
- **Remote Desktop Access**: Connect to desktops via SSH or virt-viewer with SPICE protocol
- **Windows virt-viewer Integration**: Automatic installation and management of virt-viewer on Windows
- **Hardware Information**: View CPU and memory specifications for virtual desktops
- **Session Persistence**: Automatic session management and token refresh
- **Rich CLI Experience**: Beautiful console output with status indicators and progress bars

## Installation

### From PyPI (Recommended)

```bash
pip install isard
```

### From Source

```bash
git clone https://gitlab.com/daviddemingo/isard.git
cd isard
uv sync
uv run python -m isard --help
```

## Quick Start

### Authentication

Set up your credentials using environment variables:

```bash
export GENCAT_USERNAME="your-username@edu.gencat.cat"
export GENCAT_PASSWORD="your-password"
```

Or create a `.env` file in your working directory:

```env
GENCAT_USERNAME=your-username@edu.gencat.cat
GENCAT_PASSWORD=your-password
```

### Basic Usage

```bash
# Login and display session information
isard login

# Show version
isard version

# List all virtual desktops
isard list

# List desktops with hardware specifications
isard list --hardware

# Browse available templates
isard template

# Browse templates with hardware info
isard template --hardware

# Create a new desktop
isard create "My Desktop"

# Create desktop from specific template
isard create "My Desktop" --template "Ubuntu 22.04"

# Start a desktop
isard start "Desktop Name"

# Start a desktop and wait for it to be ready
isard start "Desktop Name" --wait --timeout 300

# Stop a desktop
isard stop "Desktop Name"

# Delete a desktop (move to trash - recoverable)
isard delete "Desktop Name"

# Permanently delete a desktop (irreversible)
isard delete "Desktop Name" --permanent

# Delete with confirmation skip
isard delete "Desktop Name" --yes

# Open desktop in virt-viewer
isard view "Desktop Name"

# Open desktop with auto-start if stopped
isard view "Desktop Name" --start

# SSH into a desktop
isard ssh "Desktop Name"

# SSH with auto-start if desktop is stopped
isard ssh "Desktop Name" --start

# Logout (clear cached sessions)
isard logout
```

## Commands

| Command | Description | Options |
|---------|-------------|---------|
| `login` | Authenticate and display session info | `--username`, `--password`, `--force` |
| `logout` | Delete cached session files | - |
| `version` | Show package version | - |
| `list` | List desktops with state/IP/OS | `--hardware/-H` |
| `template` | List available templates | `--category/-c`, `--hardware/-H`, `--filter` |
| `create <name>` | Create new desktop from template | `--template/-t`, `--description/-d`, `--category/-c` |
| `start <name>` | Start a stopped desktop | `--wait/-w`, `--timeout` |
| `stop <name>` | Stop a running desktop | `--wait/-w`, `--timeout` |
| `delete <name>` | Delete desktop (trash or permanent) | `--permanent`, `--yes/-y` |
| `view <name>` | Open desktop in virt-viewer via SPICE | `--start`, `--install/--no-install` |
| `ssh <name>` | SSH into desktop via bastion | `--start`, `--user/-l`, `--identity/-i`, `--dry-run` |

### Desktop Name Resolution

The CLI intelligently resolves desktop names using:

1. **Exact match** (case-insensitive)
2. **Fuzzy matching** for typos and partial names
3. **Substring matching** as fallback

### SSH Configuration

The SSH command automatically:

- Resolves SSH private keys (`--identity`, `~/.ssh/id_ed25519`, `~/.ssh/id_rsa`)
- Generates new ed25519 keys if none found
- Registers public keys with IsardVDI bastion
- Handles bastion connection on port 443

## Authentication Flow

1. **SAML 2.0 Authentication**: Secure login via Azure Entra ID
2. **Session Caching**: Persistent sessions stored securely in `~/.config/isard/`
3. **Automatic Refresh**: JWT tokens refreshed automatically on expiration
4. **Force Refresh**: Use `--force` flag to bypass cached sessions

## Library Usage

Isard can also be used as a Python library:

```python
from isard import login_to_gencat, get_desktops, start_desktop, delete_desktop, get_templates, create_desktop, get_spice_file

# Authenticate
session = login_to_gencat("username@edu.gencat.cat", "password")

# Get desktops
desktops = get_desktops(session)

# Get available templates
templates = get_templates(session)

# Create a new desktop
desktop = create_desktop(session, template_id, "My Desktop", description="Test desktop")

# Start a desktop
start_desktop(session, desktop_id)

# Get SPICE file for remote viewing
spice_content = get_spice_file(session, desktop_id)

# Delete a desktop (move to trash)
delete_desktop(session, desktop_id)

# Permanently delete a desktop
from isard import delete_desktop_permanent
delete_desktop_permanent(session, desktop_id)
```

## Configuration

### Session Files

- `~/.config/isard/session.json` - Gencat SAML session (user info, cookies)
- `~/.config/isard/isardvdi.json` - IsardVDI JWT session (authentication token)

Both files are created with `chmod 600` for security.

### Environment Variables

- `GENCAT_USERNAME` - Your Gencat username
- `GENCAT_PASSWORD` - Your Gencat password

## Requirements

- Python 3.14 or later
- Linux, macOS, or Windows
- Internet connection for authentication
- SSH client for desktop access

## Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues on GitHub.

## License

This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). See the [LICENSE](LICENSE) file for details.

## Support

- **GitLab Issues**: [Report bugs or request features](https://gitlab.com/daviddemingo/isard/-/issues)
- **Documentation**: [View documentation](https://gitlab.com/daviddemingo/isard#readme)

---

**Note**: This tool is designed specifically for the Gencat educational platform. You'll need valid credentials for the IsardVDI system to use this tool.