This plugin enables Waldur Site Agent to manage OKD/OpenShift projects and resources, providing integration between Waldur and OKD/OpenShift clusters.
Install the plugin alongside the core waldur-site-agent package:
# Using uv (recommended)
uv sync --extra okd
# Or using pip
pip install -e plugins/okd
Create a configuration file (see examples/okd-config.yaml for a complete example):
backend_type: okd
backend_settings:
api_url: https://api.okd.example.com:8443
token: your-service-account-token
verify_cert: true
namespace_prefix: waldur-
default_role: edit
backend_components:
cpu:
measured_unit: Core
accounting_type: limit
memory:
measured_unit: GB
accounting_type: limit
storage:
measured_unit: GB
accounting_type: limit
pods:
measured_unit: Count
accounting_type: limit
The plugin supports multiple authentication methods with automatic token refresh:
For testing or when manually managing tokens:
backend_settings:
api_url: https://api.okd.example.com:8443
token: sha256~your-static-token-here
verify_cert: true
For production deployments with automatic token refresh:
backend_settings:
api_url: https://api.okd.example.com:8443
verify_cert: true
token_config:
token_type: service_account
service_account_path: /var/run/secrets/kubernetes.io/serviceaccount
When tokens are managed by external systems:
backend_settings:
api_url: https://api.okd.example.com:8443
verify_cert: true
token_config:
token_type: file
token_file_path: /etc/okd-tokens/current-token
Framework ready for OAuth-based authentication:
backend_settings:
api_url: https://api.okd.example.com:8443
verify_cert: true
token_config:
token_type: oauth
oauth_config:
client_id: your-oauth-client-id
client_secret: your-oauth-client-secret
refresh_token: your-refresh-token
token_endpoint: https://oauth.okd.example.com/oauth/token
The plugin maps Waldur organizational hierarchy to OKD/OpenShift projects and namespaces:
graph TB
subgraph "Waldur Hierarchy"
WC[Customer/Organization<br/>e.g. 'ACME Corp']
WP[Project<br/>e.g. 'Web Development']
WR[Resource/Allocation<br/>e.g. 'Production Environment']
WU[Users<br/>e.g. 'john@acme.com']
WC --> WP
WP --> WR
WC --> WU
WP --> WU
end
subgraph "OKD/OpenShift Objects"
ON[Namespace/Project<br/>waldur-alloc-prod-env]
ORQ[ResourceQuota<br/>waldur-quota]
ORB[RoleBinding<br/>waldur-users]
OSA[ServiceAccounts]
ON --> ORQ
ON --> ORB
ON --> OSA
end
subgraph "Mapping Rules"
MR1[Customer → Project Prefix]
MR2[Project → Project Metadata]
MR3[Resource → Namespace]
MR4[Users → RoleBindings]
MR5[Limits → ResourceQuota]
end
WC -.->|Prefix| ON
WP -.->|Metadata| ON
WR ==>|Creates| ON
WU -.->|Binds to| ORB
WR -.->|Sets limits| ORQ
style WR fill:#e1f5fe
style ON fill:#c8e6c9
style ORQ fill:#fff9c4
style ORB fill:#ffccbc
Waldur resources are mapped to OKD namespaces with a hierarchical naming convention:
| Waldur Object | OKD Namespace Pattern | Example |
|---|---|---|
| Customer Resource | {prefix}org-{customer_slug} |
waldur-org-acme |
| Project Resource | {prefix}proj-{project_slug} |
waldur-proj-webdev |
| Allocation Resource | {prefix}alloc-{allocation_slug} |
waldur-alloc-prod-env |
Waldur resource limits are translated to Kubernetes ResourceQuotas:
| Waldur Component | OKD ResourceQuota Field | Example |
|---|---|---|
| CPU (Cores) | requests.cpu, limits.cpu |
4 cores |
| Memory (GB) | requests.memory, limits.memory |
16Gi |
| Storage (GB) | requests.storage |
100Gi |
| Pod Count | pods |
50 |
Waldur user roles are mapped to OpenShift RoleBindings:
| Waldur Role | OpenShift ClusterRole | Permissions |
|---|---|---|
| Owner | admin |
Full namespace administration |
| Manager | edit |
Create/modify resources |
| Member | view |
Read-only access |
Waldur metadata is preserved in OKD annotations:
metadata:
name: waldur-alloc-prod-env
annotations:
waldur.com/customer-uuid: "123e4567e89b12d3a456426614174000"
waldur.com/project-uuid: "456e7890f12c34d5b678537825285111"
waldur.com/resource-uuid: "789a0123g34h56i7j890648936396222"
waldur.com/customer-name: "ACME Corp"
waldur.com/project-name: "Web Development"
labels:
waldur.com/managed: "true"
waldur.com/customer: "acme"
waldur.com/project: "webdev"
The plugin requires a service account token with specific permissions to manage OKD/OpenShift resources. The token must have cluster-level permissions to create and manage projects, namespaces, resource quotas, and role bindings.
The service account needs the following permissions:
Create a service account for the Waldur Site Agent:
# Create service account in the desired namespace
oc create serviceaccount waldur-site-agent -n waldur-system
# Alternative: Use the default namespace
oc create serviceaccount waldur-site-agent -n default
Create a ClusterRole with necessary permissions:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: waldur-site-agent
rules:
# OpenShift project management
- apiGroups: ["project.openshift.io"]
resources: ["projects", "projectrequests"]
verbs: ["create", "delete", "get", "list", "patch", "update"]
# Kubernetes namespace and resource quota management
- apiGroups: [""]
resources: ["namespaces", "resourcequotas"]
verbs: ["create", "delete", "get", "list", "patch", "update"]
# User access management through role bindings
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["create", "delete", "get", "list", "patch", "update"]
# Resource monitoring and usage reporting
- apiGroups: [""]
resources: ["pods", "services", "persistentvolumeclaims"]
verbs: ["get", "list"]
# API discovery for cluster connectivity checks
- apiGroups: [""]
resources: [""]
verbs: ["get"]
Bind the role to the service account:
# Bind the cluster role to the service account
oc adm policy add-cluster-role-to-user waldur-site-agent -z waldur-site-agent -n waldur-system
# Alternative: Using oc create command
oc create clusterrolebinding waldur-site-agent \
--clusterrole=waldur-site-agent \
--serviceaccount=waldur-system:waldur-site-agent
Create a long-lived token for production use:
# OpenShift 4.11+ (recommended for production)
oc create token waldur-site-agent \
--namespace=waldur-system \
--duration=8760h \
--bound-object-kind=Secret \
--bound-object-name=waldur-site-agent-token
# Create a secret-bound token for enhanced security
oc apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: waldur-site-agent-token
namespace: waldur-system
annotations:
kubernetes.io/service-account.name: waldur-site-agent
type: kubernetes.io/service-account-token
EOF
# Get the token from the secret
oc get secret waldur-site-agent-token -n waldur-system -o jsonpath='{.data.token}' | base64 -d
Create a temporary token for testing:
# OpenShift 4.x (24 hour expiration)
oc create token waldur-site-agent --namespace=waldur-system
# OpenShift 3.x (legacy method)
oc sa get-token waldur-site-agent -n waldur-system
Verify the token has correct permissions:
# Test basic API access
curl -k -H "Authorization: Bearer YOUR_TOKEN" \
"https://your-okd-api:6443/api/v1"
# Test project creation permissions
curl -k -H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
"https://your-okd-api:6443/apis/project.openshift.io/v1/projectrequests" \
-X POST -d '{
"kind": "ProjectRequest",
"apiVersion": "project.openshift.io/v1",
"metadata": {"name": "test-waldur-permissions"},
"displayName": "Test Permissions"
}'
# Clean up test project
oc delete project test-waldur-permissions
Run the agent with your configuration:
waldur_site_agent -m event_process -c okd-config.yaml
order_process: Process orders from Waldur to create/modify OKD projectsreport: Report resource usage from OKD to Waldurmembership_sync: Synchronize user memberships between Waldur and OKDevent_process: Process events via STOMP (if configured)For real-time event processing, configure STOMP settings in your configuration file:
# Event processing mode configuration
agent_mode: event_process
# STOMP configuration for event processing
event_processing:
stomp_host: your-stomp-broker.example.com
stomp_port: 61613
stomp_username: waldur-agent
stomp_password: your-secure-password
stomp_destination: /queue/waldur.events
stomp_ssl: true
stomp_heartbeat: 10000 # milliseconds
Resource quotas are automatically created for each project based on Waldur resource allocations. The quotas enforce both request and limit constraints for:
requests.cpu and limits.cpurequests.memory and limits.memoryUsers from Waldur are automatically granted access to OKD projects through RoleBindings. The plugin maps Waldur roles to OpenShift ClusterRoles for fine-grained access control.
Run the plugin tests:
# Run all OKD plugin tests
uv run pytest plugins/okd/tests/
# Run specific test
uv run pytest plugins/okd/tests/test_okd_backend.py::TestOkdBackend::test_create_resource
The plugin automatically handles token expiration and refresh:
If authentication fails:
Verify Token Validity:
# Test token directly
curl -k -H "Authorization: Bearer YOUR_TOKEN" \
"https://your-okd-api:6443/api/v1"
Check Token Expiration:
# Decode JWT token (if using JWT format)
echo "YOUR_TOKEN" | cut -d'.' -f2 | base64 -d | jq .exp
Validate Service Account Permissions:
# Check if service account exists
oc get serviceaccount waldur-site-agent -n waldur-system
# Verify cluster role binding
oc get clusterrolebinding waldur-site-agent
If the agent cannot connect to the OKD cluster:
verify_cert: falseIf operations fail with permission errors:
If automatic token refresh fails:
Enable debug logging for detailed token management information:
# Set log level to DEBUG in configuration
log_level: DEBUG
# Or use environment variable
WALDUR_LOG_LEVEL=DEBUG waldur_site_agent -m order_process -c okd-config.yaml
Run diagnostics to verify configuration:
# Standard diagnostics
waldur_site_diagnostics -c okd-config.yaml
plugins/okd/
├── waldur_site_agent_okd/
│ ├── __init__.py
│ ├── backend.py # Main backend implementation
│ ├── client.py # OKD API client with SSL handling
│ └── token_manager.py # Authentication token management
├── tests/
│ └── test_okd_backend.py
├── examples/
│ ├── okd-config.yaml
│ └── okd-config-with-token-refresh.yaml
├── pyproject.toml
└── README.md
backend.py: Main plugin implementation extending BaseBackendclient.py: OKD API client with SSL adapter and authentication integrationtoken_manager.py: Comprehensive token management system supporting:
OkdClient class for new API operationsOkdBackend class to use new client methodsThis plugin is part of the Waldur Site Agent project and follows the same license terms.