Automatic Provisioning¶
The SLURM PowerAutomate system begins when applicants fill out a Microsoft Form requesting access. Power Automate sends an adaptive card to administrators for approval or denial. Upon approval, Power Automate updates a shared Excel file on OneDrive with the request details. The SLURM server periodically checks this Excel file for changes, automatically processing approved "new" requests by creating LDAP accounts with home directories and adding them to the proper advisor/student group, and "extension" requests by modifying account expiration dates. After successful processing, the server updates the Excel file with generated usernames and passwords, triggering Power Automate to send an email to the applicant with their credentials and access details. This end-to-end automation eliminates manual intervention while maintaining proper approval workflows and audit trails.
Power Automate Flow¶
The current Power Automate setup is not flexible enough, resulting in two separate flows for the new-user and extension scenarios. Each pair of flows is largely similar, with only minor differences, and there are also two separate flows dedicated to sending emails for these cases.
2 Flows Triggered by New Form Submission¶
Adaptive Card JSON
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "📝 New Resource Request Received",
"weight": "Bolder",
"size": "Large"
},
{
"type": "TextBlock",
"text": "📧 KFUPM Email: @{outputs('Get_response_details')?['body/responder']}",
"wrap": true
},
{
"type": "TextBlock",
"text": "🏫 Academic Department: @{replace(replace(outputs('Get_response_details')?['body/ra7f68cb1b98841d7bbe8534dfa405e37'], '\', '\\'), '"', '\"')}",
"wrap": true
},
{
"type": "TextBlock",
"text": "📚 Topic Description: @{replace(replace(outputs('Get_response_details')?['body/r49b61f1dfb7b464bbdaaf11899aa8c74'], '\', '\\'), '"', '\"')}",
"wrap": true
},
{
"type": "TextBlock",
"text": "⏳ Period of Access: @{outputs('Get_response_details')?['body/r76be5d1721bf4706b7c0e999a77aa517']} Days",
"wrap": true
},
{
"type": "TextBlock",
"text": "📢 Publication Acknowledgement: @{outputs('Get_response_details')?['body/r80a67ac6574e495bbbc43dd0054e71b4']}",
"wrap": true
},
{
"type": "TextBlock",
"text": "🗒 Additional Comments: @{replace(replace(outputs('Get_response_details')?['body/rd1e2f20f721b4538a138760a850b7e97'], '\', '\\'), '"', '\"')}",
"wrap": true
}
],
"actions": [
{
"type": "Action.ShowCard",
"title": "✅ Approve",
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "Are you sure you want to approve this request?"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Confirm Approval",
"data": {
"approval": "Approve"
}
}
]
}
},
{
"type": "Action.ShowCard",
"title": "❌ Reject",
"card": {
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "Please confirm rejection and optionally explain why."
},
{
"type": "Input.Text",
"id": "rejectionReason",
"placeholder": "Enter reason (optional)",
"isMultiline": true
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Confirm Rejection",
"data": {
"approval": "Reject"
}
}
]
}
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.4"
}
New User Requests¶
New Extension Requests¶
Flow: Newly Created Users (Every 10 min)¶
Flow: Newly Extended Users (Every 10 min)¶
Excel Schema¶
The shared "Responses" Excel sheet on OneDrive. Each field and where it comes from:
- ReqID —
Form/Power Automate - Request Date —
Form/Power Automate - Request Type —
Form/Power Automate - KFUPM_Email —
Form/Power Automate - Full Name —
Form/Power Automate - Department —
Form/Power Automate - Topic —
Form/Power Automate - AccessDays —
Form/Power Automate - Acknowledgement —
Form/Power Automate - Comments —
Form/Power Automate - ApprovalStatus —
Approve/Deny on Teams / Power Automate - Created —
Server Script - Username —
Server Script - Password —
Server Script - Notified —
Power Automate - Extended —
Server Script
See Server Scripts for what actually reads/writes these columns.
Server Scripts¶
Scripts path: /opt/slurm-powerautomate
The server runs Python scripts that handle the core user management operations. slurm_main.py serves as the main orchestrator, reading the Excel file once and processing both creation and extension requests efficiently. slurm_auto_create.py and slurm_auto_extend.py handle the specific logic for new accounts and expiration extensions respectively. Core functionality is provided by ldap_manager.py for LDAP operations, onedrive_manager.py for Excel integration, system_manager.py for Linux operations, slurm_manager.py for SLURM accounts and associations, and utils.py for common functions. All scripts integrate with LDAP for authentication, XFS quotas for storage limits, and SLURM account association, ensuring complete user provisioning in a single automated workflow.
slurm_main.py¶
Main orchestrator that reads the Excel file once and coordinates both creation and extension processing. Runs with configurable modes (--create, --extend, --both) for flexible operation. Invoked automatically by slurm-powerautomate.service.
utils.py¶
Common utility functions including logging setup, username generation from emails, and password creation. Contains Excel column mapping and helper functions used across all modules.
slurm_auto_create.py¶
Processes "new" user requests by generating usernames/passwords and creating complete SLURM accounts. Updates Excel with generated credentials upon successful account creation.
slurm_auto_extend.py¶
Handles "extension" requests by modifying LDAP shadowExpire attributes to extend account access. Updates Excel with extension confirmation once processing is complete.
onedrive_manager.py¶
Microsoft OneDrive integration for Excel file operations using OAuth authentication. Provides methods to read Excel data and update individual cells with processing results.
ldap_manager.py¶
Core LDAP operations including user creation, expiration management, and account deletion. Handles SSHA password hashing.
system_manager.py¶
Handles home directory creation and (previously) XFS quota setting — see Disk Quotas (XFS, old).
slurm_manager.py¶
Handles SLURM association.
systemd Services¶
For this to automatically work and check for changes in the Excel sheet, it has to be linked with a systemd service and timer.
slurm-powerautomate.servicerunsslurm_main.pywith--both.slurm-powerautomate.timermakes it check every 3 minutes.
slurm-powerautomate.service¶
Path: /etc/systemd/system/slurm-powerautomate.service
[Unit]
Description=SLURM PowerAutomate Account Processor
After=network.target
[Service]
Type=oneshot
User=root
EnvironmentFile=/etc/slurm-powerautomate/credentials
WorkingDirectory=/opt/slurm-powerautomate
ExecStart=/opt/anaconda3/bin/python /opt/slurm-powerautomate/slurm_main.py --both
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
slurm-powerautomate.timer¶
Path: /etc/systemd/system/slurm-powerautomate.timer
[Unit]
Description=Run SLURM PowerAutomate processor every 3 minutes
Requires=slurm-powerautomate.service
[Timer]
OnCalendar=*:0/3:00
Persistent=true
[Install]
WantedBy=timers.target
If this fails
See Power Automate Auth Failure for the most common failure mode (an expired OAuth token cache).



