Skip to main content

Harbor container registry plugin for Waldur Site Agent

Project description

Harbor Container Registry Plugin for Waldur Site Agent

This plugin provides production-ready integration between Waldur Mastermind and Harbor container registry, enabling automated management of Harbor projects, storage quotas, and OIDC-based access control.

Features

  • ✅ Automated Project Management: Creates Harbor projects for each Waldur resource
  • ✅ Storage Quota Management: Configurable storage limits with usage tracking
  • ✅ OIDC Integration: Automatic OIDC group creation and assignment for access control
  • ✅ Usage Reporting: Reports container storage usage back to Waldur for billing
  • ✅ Robot Account Authentication: Uses Harbor robot accounts for API operations
  • ✅ Production Ready: All operations tested and working with Harbor API v2.0

Architecture & Mapping

Waldur ↔ Harbor Resource Mapping

graph TB
    subgraph "Waldur Mastermind"
        WC[Waldur Customer<br/>customer-slug]
        WP[Waldur Project<br/>project-slug]
        WR1[Waldur Resource 1<br/>resource-slug-1]
        WR2[Waldur Resource 2<br/>resource-slug-2]
        WU1[Waldur User 1]
        WU2[Waldur User 2]
        WU3[Waldur User 3]
    end

    subgraph "Harbor Registry"
        HG[OIDC Group<br/>waldur-project-slug]
        HP1[Harbor Project 1<br/>waldur-resource-slug-1]
        HP2[Harbor Project 2<br/>waldur-resource-slug-2]
        HQ1[Storage Quota 1<br/>e.g., 10GB]
        HQ2[Storage Quota 2<br/>e.g., 20GB]
        HR1[Container Repos 1]
        HR2[Container Repos 2]
    end

    subgraph "OIDC Provider"
        OG[OIDC Group<br/>waldur-project-slug]
        OU1[OIDC User 1]
        OU2[OIDC User 2]
        OU3[OIDC User 3]
    end

    %% Relationships
    WC --> WP
    WP --> WR1
    WP --> WR2
    WP --> WU1
    WP --> WU2
    WP --> WU3

    %% Waldur to Harbor mapping
    WR1 -.->|"1:1 mapping"| HP1
    WR2 -.->|"1:1 mapping"| HP2
    WP -.->|"1:1 mapping"| HG

    %% Harbor internal relationships
    HG -->|"Developer role"| HP1
    HG -->|"Developer role"| HP2
    HP1 --> HQ1
    HP2 --> HQ2
    HP1 --> HR1
    HP2 --> HR2

    %% OIDC relationships
    WU1 -.->|"SSO identity"| OU1
    WU2 -.->|"SSO identity"| OU2
    WU3 -.->|"SSO identity"| OU3
    OU1 --> OG
    OU2 --> OG
    OU3 --> OG
    HG -.->|"Same group"| OG

    %% Styling
    classDef waldur fill:#e1f5fe
    classDef harbor fill:#fff3e0
    classDef oidc fill:#f3e5f5

    class WC,WP,WR1,WR2,WU1,WU2,WU3 waldur
    class HG,HP1,HP2,HQ1,HQ2,HR1,HR2 harbor
    class OG,OU1,OU2,OU3 oidc

Key Mapping Rules

  1. Waldur ResourceHarbor Project (1:1)

    • Each Waldur resource creates a separate Harbor project
    • Provides complete isolation between different registry resources
    • Project names: {allocation_prefix}{resource_slug}
  2. Waldur ProjectOIDC Group (1:1)

    • One OIDC group per Waldur project for access control
    • All project team members get access to ALL Harbor projects within the Waldur project
    • Group names: {oidc_group_prefix}{project_slug}
  3. Storage Management

    • Each Harbor project gets individual storage quota
    • Quotas set based on Waldur resource limits
    • Usage reported back to Waldur for billing

Installation

  1. Install the plugin alongside waldur-site-agent:
# From the workspace root
uv sync --all-packages
  1. Configure the plugin in your waldur-site-agent configuration file

Configuration

Add the Harbor backend configuration to your waldur-site-agent-config.yaml:

offerings:
  harbor-registry:
    backend_type: harbor
    backend_settings:
      # Harbor instance URL
      harbor_url: "https://harbor.example.com"

      # Robot account credentials (ensure robot has sufficient permissions)
      robot_username: "robot$waldur-agent"
      robot_password: "your-robot-password-here"

      # Default storage quota in GB for new projects
      default_storage_quota_gb: 10

      # Naming prefixes
      oidc_group_prefix: "waldur-"      # OIDC groups: waldur-{project_slug}
      allocation_prefix: "waldur-"      # Harbor projects: waldur-{resource_slug}

      # Harbor project role for OIDC groups
      # 1=Admin, 2=Developer (recommended), 3=Guest, 4=Maintainer
      project_role_id: 2

    backend_components:
      storage:
        measured_unit: "GB"
        accounting_type: "limit"
        label: "Container Storage"
        unit_factor: 1

    # Waldur API settings
    api_url: "https://waldur.example.com/api/"
    api_token: "your-waldur-api-token"

    # Offering UUID in Waldur
    offering_uuid: "harbor-offering-uuid"

Robot Account Permissions

Critical: The Harbor robot account must have the following permissions:

  • Project creation (POST /api/v2.0/projects)
  • Project deletion (DELETE /api/v2.0/projects/{id}) - REQUIRED for proper resource lifecycle
  • Quota management (GET/PUT /api/v2.0/quotas)
  • User group management (GET/POST /api/v2.0/usergroups)
  • Project member management (GET/POST/DELETE /api/v2.0/projects/{id}/members)

✅ Verified: All operations including project deletion are working with proper system-level robot account permissions.

Harbor Setup

1. Create Robot Account

  1. Login to Harbor as admin
  2. Navigate to Administration → Robot Accounts
  3. Create a new robot account with system-level permissions:
    • Level: System (not project-specific)
    • Permissions:
      • Project: Create, Read, Update, Delete
      • Resource: Create, Read, Update
      • Member: Create, Read, Update, Delete
      • Quota: Read, Update
  4. Save the credentials for configuration

Note: The robot account needs system-level permissions to delete projects. Project-level robot accounts cannot delete their own projects.

2. Configure OIDC Authentication

  1. Navigate to Administration → Configuration → Authentication
  2. Set Auth Mode to "OIDC"
  3. Configure OIDC provider settings:
    • OIDC Endpoint: Your identity provider URL
    • OIDC Client ID: Harbor client ID in your IdP
    • OIDC Client Secret: Harbor client secret
    • OIDC Scope: openid,email,profile,groups
    • Group Claim Name: groups (or your IdP's group claim)

3. Configure Storage Quotas

  1. Navigate to Administration → Configuration → System Settings
  2. Set appropriate global storage quota limits
  3. Individual project quotas will be managed by the agent

Usage

Running the Agent

# Process orders (create/delete Harbor projects)
uv run waldur_site_agent -m order_process -c config.yaml

# Report usage back to Waldur
uv run waldur_site_agent -m report -c config.yaml

# Synchronize memberships (OIDC group management)
uv run waldur_site_agent -m membership_sync -c config.yaml

Systemd Service

Create a systemd service for automated operation:

[Unit]
Description=Waldur Harbor Agent - Order Processing
After=network.target

[Service]
Type=simple
User=waldur
ExecStart=/usr/local/bin/waldur_site_agent -m order_process -c /etc/waldur/harbor-config.yaml
Restart=on-failure
RestartSec=60

[Install]
WantedBy=multi-user.target

API Operations

The plugin implements the following Harbor API operations:

✅ Project Management (Fully Working)

  • ✅ Create project with minimal payload
  • ✅ Get project details and metadata
  • ✅ List all projects
  • Delete project (complete resource lifecycle)

✅ Storage Quota Management (Fully Working)

  • ✅ Set project storage quotas
  • ✅ Update project storage quotas
  • ✅ Query current quota usage
  • ✅ Report storage consumption for billing

✅ OIDC Group Management (Fully Working)

  • ✅ Create OIDC groups
  • ✅ Assign groups to projects with specified roles (Admin/Developer/Guest/Maintainer)
  • ✅ List existing user groups
  • ✅ Search for specific groups

✅ Usage Reporting (Fully Working)

  • ✅ Query project storage usage via quota API
  • ✅ Report repository counts
  • ✅ Track storage consumption for Waldur billing
  • ✅ Get project metadata and statistics

🔄 Supported Waldur Operations

  • order_process: Create/update Harbor projects and quotas
  • report: Report storage usage back to Waldur
  • membership_sync: Manage OIDC group memberships
  • diagnostics: Health checks and connectivity testing

Testing

Run the test suite:

# Run all Harbor plugin tests
uv run pytest plugins/harbor/tests/ -v

# Run with coverage
uv run pytest plugins/harbor/tests/ --cov=waldur_site_agent_harbor

Troubleshooting

✅ Known Issues & Solutions

1. CSRF Token Errors (SOLVED)

Symptom: 403 Forbidden - CSRF token not found in request

Root Cause: Harbor's session-based authentication requires CSRF tokens for persistent sessions.

✅ Solution: The plugin now uses direct HTTP requests with authentication tuples instead of persistent sessions, which bypasses CSRF requirements entirely.

Technical Details:

# OLD (caused CSRF issues)
session = requests.Session()
session.headers.update({"Authorization": "Basic ..."})
response = session.post(url, json=data)

# NEW (works perfectly)
auth = (username, password)
response = requests.post(url, auth=auth, json=data)

2. Robot Account Permissions

Symptoms:

  • Can list projects but cannot create them
  • Can create projects but cannot set quotas
  • Cannot create OIDC groups

✅ Solution: Ensure robot account has system-level permissions:

  1. Login to Harbor as admin
  2. Go to Administration → Robot Accounts
  3. Edit your robot account
  4. Grant these system-level permissions:
    • Project: Create, Read, Update, Delete
    • Resource: Create, Read, Update
    • Member: Create, Read, Update, Delete
    • Quota: Read, Update

Critical: Without project deletion permissions, Harbor projects will accumulate when Waldur resources are terminated, leading to storage waste and potential quota issues.

Common Issues

  1. Authentication Failures

    • ✅ Verify robot account credentials in configuration
    • ✅ Test connectivity: curl -u "robot\$user:pass" https://harbor.example.com/api/v2.0/health
    • ✅ Ensure Harbor API v2.0 is enabled
  2. OIDC Group Issues

    • ✅ Verify OIDC configuration in Harbor (Administration → Configuration → Authentication)
    • ✅ Check group claim configuration (groups is common)
    • ✅ Ensure OIDC provider is properly configured
  3. Storage Quota Problems

    • ✅ Check global quota settings in Harbor (Administration → Configuration → System Settings)
    • ✅ Verify project-specific quotas: curl -u "robot\$user:pass" https://harbor.example.com/api/v2.0/quotas
    • ✅ Monitor Harbor system storage availability

Debugging

Enable Debug Logging

# In waldur-site-agent config
logging:
  level: DEBUG
  format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"

Test Harbor Client Directly

from waldur_site_agent_harbor.client import HarborClient

client = HarborClient("https://harbor.example.com", "robot$user", "password")

# Test connectivity
print("Ping:", client.ping())

# List projects
projects = client.list_resources()
print("Projects:", [p.name for p in projects])

# Test permissions
try:
    # This should work if permissions are correct
    group_id = client.create_user_group("test-group")
    print("Group created:", group_id)
except Exception as e:
    print("Permission issue:", e)

Check Logs

# For systemd deployments
journalctl -u waldur-harbor-agent -f --since "1 hour ago"

# For direct execution
tail -f /var/log/waldur-site-agent.log

Verification Commands

Test robot account permissions manually:

# Test authentication
curl -u "robot\$username:password" https://harbor.example.com/api/v2.0/health

# Test project listing
curl -u "robot\$username:password" https://harbor.example.com/api/v2.0/projects

# Test quota access
curl -u "robot\$username:password" https://harbor.example.com/api/v2.0/quotas

# Test group management
curl -u "robot\$username:password" https://harbor.example.com/api/v2.0/usergroups

# Test project deletion permissions (CRITICAL)
# First create a test project
curl -X POST -H "Content-Type: application/json" \
  -u "robot\$username:password" \
  -d '{"project_name":"deletion-test","metadata":{"public":"false"}}' \
  https://harbor.example.com/api/v2.0/projects

# Then try to delete it (should return 200/204, not 403)
# Get project ID first, then delete
curl -X DELETE -u "robot\$username:password" \
  https://harbor.example.com/api/v2.0/projects/{project_id}

Expected Results

  • 200/201 for creation operations
  • 200 for read operations
  • 200/204 for update operations
  • 200/204 for deletion operations
  • 403 Forbidden indicates insufficient permissions

Development

Project Structure

plugins/harbor/
├── waldur_site_agent_harbor/
│   ├── __init__.py
│   ├── backend.py       # HarborBackend implementation
│   ├── client.py        # Harbor API client
│   └── exceptions.py    # Custom exceptions
├── tests/
│   ├── test_harbor_backend.py
│   └── test_harbor_client.py
├── pyproject.toml
└── README.md

Adding New Features

  1. Extend the HarborClient class for new API operations
  2. Update HarborBackend to utilize new client methods
  3. Add corresponding tests
  4. Update documentation

License

This plugin is part of the Waldur Site Agent project and follows the same licensing terms.

Support

For issues and questions:

  • Create an issue in the Waldur Site Agent repository
  • Contact the OpenNode team

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

waldur_site_agent_harbor-0.8.4.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

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

waldur_site_agent_harbor-0.8.4-py3-none-any.whl (15.8 kB view details)

Uploaded Python 3

File details

Details for the file waldur_site_agent_harbor-0.8.4.tar.gz.

File metadata

  • Download URL: waldur_site_agent_harbor-0.8.4.tar.gz
  • Upload date:
  • Size: 17.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.2","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for waldur_site_agent_harbor-0.8.4.tar.gz
Algorithm Hash digest
SHA256 8df0276e23944934364ffbc6a1793bd1b8ee837698cf781dc693530b1e108619
MD5 4bc7ce6c9874ea3c6e9b5699549a06a8
BLAKE2b-256 7bee5dbfada264fc16c0af2cfcea2e69e83ee2e311d9c20c53ac521fc2d4dde7

See more details on using hashes here.

File details

Details for the file waldur_site_agent_harbor-0.8.4-py3-none-any.whl.

File metadata

  • Download URL: waldur_site_agent_harbor-0.8.4-py3-none-any.whl
  • Upload date:
  • Size: 15.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.2","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for waldur_site_agent_harbor-0.8.4-py3-none-any.whl
Algorithm Hash digest
SHA256 394f832c7f0525dbda819b90f3a20be5a527ff8fb45bd2a3ac0b55b48d57eb94
MD5 c57d23af0e10b41d7e55b639968beb40
BLAKE2b-256 6128d97963874a686486c160179d46aad818496a6c9a1ef7f4d6417fc650782d

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