lab-resource-manager 0.3.0

GPU and room resource management system with Google Calendar and Slack integration
Documentation

lab-resource-manager

Crates.io Documentation License

GPU and room resource usage management and notification system.

日本語 README

Features

  • Resource Usage Management: Manage GPU server and room usage schedules (default implementation: Google Calendar)
  • Slack Bot for Access Control: Users can register their email addresses and get resource access via Slack commands
    • Support for DMs and private channels via response_url
    • Automatic user mentions in notifications
  • Identity Linking: Map email addresses to chat user IDs for enhanced notifications
  • Multi-Destination Notifications: Configure different notification destinations per resource (default implementations: Slack, Mock)
  • Flexible Device Specification: Support for multi-device notation like 0-2,5,7-9
  • Clean Architecture: Designed with DDD + Hexagonal Architecture with Shared Kernel pattern
  • Extensible Design: Repositories, notifiers, and access control services abstracted as ports

Architecture

This project follows Clean Architecture principles:

src/
├── domain/                  # Domain layer (business logic)
│   ├── aggregates/          # Aggregates (ResourceUsage, IdentityLink)
│   ├── common/              # Shared Kernel (EmailAddress, etc.)
│   ├── ports/               # Ports (Repository, Notifier, ResourceCollectionAccess traits)
│   └── errors.rs            # Domain errors
├── application/             # Application layer (use cases)
│   └── usecases/            # Notify, GrantAccess use cases
├── infrastructure/          # Infrastructure layer (external integrations)
│   ├── repositories/        # Repository implementations (Google Calendar, JSON file, etc.)
│   │   ├── resource_usage/  # ResourceUsage repository implementations
│   │   └── identity_link/   # IdentityLink repository implementations
│   ├── notifier/            # Notifier implementations (Slack, Mock, etc.)
│   ├── resource_collection_access/ # Access control service implementations (Google Calendar, etc.)
│   └── config/              # Configuration management
├── interface/               # Interface layer (adapters)
│   └── slack/               # Slack bot (Socket Mode + command handlers)
└── bin/                     # Entry points
    ├── watcher.rs           # Resource usage watcher
    └── slackbot.rs          # Slack bot for resource access management

Setup

1. Environment Variables

cp .env.example .env

Edit .env to configure:

# Repository Configuration (default implementation: Google Calendar)
GOOGLE_SERVICE_ACCOUNT_KEY=secrets/service-account.json

# Resource Configuration
RESOURCE_CONFIG=config/resources.toml

# Slack Bot Configuration (for slackbot binary)
SLACK_BOT_TOKEN=xoxb-your-bot-token-here
SLACK_APP_TOKEN=xapp-your-app-token-here

Note: Notification settings are configured in config/resources.toml per resource.

2. Repository Implementation Setup (Default: Google Calendar)

If using the Google Calendar repository:

  1. Create a project in Google Cloud Console
  2. Enable Google Calendar API
  3. Create a service account and download JSON key
  4. Place the key as secrets/service-account.json
  5. Share your calendar with the service account email

3. Resource Configuration

Define GPU servers and rooms in config/resources.toml:

[[servers]]
name = "Thalys"
calendar_id = "your-calendar-id@group.calendar.google.com"  # Repository implementation-specific ID

# Configure notification destinations per resource
[[servers.notifications]]
type = "slack"  # Notifier implementation selection
webhook_url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"

# Optional: Add mock notifications for testing
# [[servers.notifications]]
# type = "mock"

[[servers.devices]]
id = 0
model = "A100 80GB PCIe"

[[servers.devices]]
id = 1
model = "A100 80GB PCIe"

[[rooms]]
name = "Meeting Room A"
calendar_id = "room-calendar-id@group.calendar.google.com"

[[rooms.notifications]]
type = "slack"
webhook_url = "https://hooks.slack.com/services/YOUR/ROOM/WEBHOOK"

Each resource can have multiple notifier implementations configured, and different resources can specify different notification destinations.

Usage

Running the Watcher

# Default (repository implementation + configured notifications)
cargo run --bin watcher

# Use mock repository (for testing)
cargo run --bin watcher --repository mock

# Customize polling interval (default: 60 seconds)
cargo run --bin watcher --interval 30

CLI Options

  • --repository <google_calendar|mock>: Select repository implementation
  • --interval <seconds>: Set polling interval

Notifier implementations are configured per resource in config/resources.toml.

Running the Slack Bot

The Slack bot allows users to register their email addresses and get access to all resource collections:

# Run the bot
cargo run --bin slackbot

Slack Commands:

  • /register-calendar <your-email@example.com> - Register your own email address and link to your Slack account
  • /link-user <@slack_user> <email@example.com> - Link another user's email address to their Slack account

Using as a Library

Add to your Cargo.toml:

[dependencies]
lab-resource-manager = "0.1"

Example code (using Google Calendar implementation):

use lab_resource_manager::prelude::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration
    let config = load_config("config/resources.toml")?;

    // Create repository implementation (using Google Calendar here)
    let repository = GoogleCalendarUsageRepository::new(
        "secrets/service-account.json",
        config.clone(),
    ).await?;

    // Create notification router (automatically handles all configured notifier implementations)
    let notifier = NotificationRouter::new(config);

    // Create and run use case
    let usecase = NotifyResourceUsageChangesUseCase::new(repository, notifier).await?;
    usecase.poll_once().await?;

    Ok(())
}

See examples/ for more usage patterns.

Development

Running Tests

# All tests
cargo test

# Specific module
cargo test resource_factory

# With output
cargo test -- --nocapture

Building

# Development build
cargo build

# Release build
cargo build --release

Code Quality

cargo check
cargo clippy
cargo fmt

Device Specification Format

In resource usage titles, you can specify devices using the following formats:

  • Single: 0 → Device 0
  • Range: 0-2 → Devices 0, 1, 2
  • Multiple: 0,2,5 → Devices 0, 2, 5
  • Mixed: 0-1,6-7 → Devices 0, 1, 6, 7

The ResourceFactory in the domain layer handles parsing these specifications.

Project Status

Implemented ✅

  • Resource-based notification routing
  • Identity Linking (chat user mapping)
  • Slack bot for resource collection access management

Roadmap

  • Slack command for creating resource usage reservations
  • Natural language resource management (LLM agent)
  • Web UI for resource management

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Acknowledgments

Developed for laboratory resource management at Kano Lab.