Automation Request Approval
If we submit an automation request to the RESTful API using the credentials of an admin user (or equivalent), we can specify :auto_approve => true in the REST call and our request will be auto-approved and immediately executed. We usually don't want to embed admin credentials in our external (calling) scripts however, so how can we still get our automation requests auto-approved?
Implementing an Approval Workflow for Automation Requests
We can implement our own approval workflow for automation requests. This example uses a group profile to control which groups can submit auto-approved automation requests.
Namespace
We'll create a new namespace called Automation under our Domain.
Group Profile
We create a simple variant of the VM Provisioning Group Profile:

The Profile merely contains the name of the Auto-Approval State Machine Instance that will be used to determine whether or not the request is auto-approved. The profile is queried using the message get_auto_approval_state_machine_instance, and returns the Value field via a collect as /state_machine_instance.
We'll allow members of group Bit63Group_vm_user to have their requests auto-approved, and everyone else (including Admins who haven't specified :auto_approve => true) will require explicit approval.
The Profile for Bit63Group_vm_user is:

The .missing Profile for all other groups is:

State Machine
We'll create a StateMachines Namespace, and a simple variant of the VM ProvisionRequestApproval class:

Instances
The RequireApproval Instance has an approval_type value of require_approval:

The Auto Instance is similar, but has an approval_type value of auto.
Methods
The validate_request Method is as follows:
request = $evm.root['miq_request']
resource = request.resource
raise "Automation Request not found" if request.nil? || resource.nil?
$evm.log("info", "Checking for auto_approval")
approval_type = $evm.object['approval_type'].downcase
if approval_type == 'auto'
$evm.root["miq_request"].approve("admin", "Auto-Approved")
$evm.root['ae_result'] = 'ok'
else
msg = "Request was not auto-approved"
resource.set_message(msg)
$evm.root['ae_result'] = 'error'
$evm.object['reason'] = msg
end
The pending_request Method is as follows:
#
# Description: This method is executed when the automation request is NOT auto-approved
#
# Get objects
msg = $evm.object['reason']
$evm.log('info', "#{msg}")
# Raise automation event: request_pending
$evm.root["miq_request"].pending
The Method definition is also given an input parameter with Input Name reason and Data Type string
The approve_request Method is as follows:
#
# Description: This method is executed when the automation request is auto-approved
#
# Auto-Approve request
$evm.log("info", "AUTO-APPROVING automation request")
$evm.root["miq_request"].approve("admin", "Auto-Approved")
Email Classes
We create an Email Class, with AutomationRequest_Pending Instance and Method:

The code is copied and adapted as appropriate from the VM ProvisionRequest_Pending Method. We specify as the to_email_address a user that will act as approver for the automation requests.
The full code for the Methods is here
Policies
We need to generate Policy Instances for two AutomationRequest events, AutomationRequest_created and AutomationRequest_approved. We copy the standard /System/Policy Class to our Domain, and add two Instances:

AutomationRequest_created
Our Policy Instance for AutomationRequest_created has three entries; an assertion and two relationships. We need to recognise whether an automation request was made with the :auto_approve => true parameter. If it was, we need to skip our own approval workflow.
We know (from some investigative debugging using object_walker) that when a request is made that specifies :auto_approve => true, we have an $evm.root['automation_request'].approval_state attribute with a value of approved. When a request is made that specifies :auto_approve => false this value is pending_approval. We can therefore create our assertion to look for $evm.root['automation_request'].approval_state == 'pending_approval', and only continue with the Instance if the boolean test returns true.
The rel5 Relationship of this Instance performs a Profile lookup based on our user group, to find the Auto-Approval State Machine Instance that should be run.
The rel6 Relationship calls this State Machine Instance:

AutomationRequest_pending
The AutomationRequest_pending Instance contains a single relationship to our AutomationRequest_pending Email Instance:

Testing
We'll submit three automation requests via the RESTful API, calling a simple Test Instance. The calls will be made as follows:
- As user admin, specifying
:auto_approve => true - As user admin, specifying
:auto_approve => false - As a user who is a member of the group Bit63Group_vm_user
For the first call, our assertion correctly prevents our custom approval workflow from running (the request has already been auto-approved). From automation.log we see:
Evaluating substituted assertion ["approved" == "pending_approval"]
Assertion Failed: <"approved" == "pending_approval">
Followed Relationship [miqaedb:/System/Policy/AutomationRequest_created#create]
Followed Relationship [miqaedb:/System/Policy/request_created#create]
Followed Relationship [miqaedb:/System/Event/request_created#create]
For the second call we see that the assertion evaulates to true, but the user admin's group (EVMGroup-super_administrator) doesn't have a group profile. The .missing profile is used, and the automation requuest is not auto-approved.
The admin user receives an email:
Request was not auto-approved.
Please review your Request and update or wait for approval from an Administrator.
To view this Request go to: https://192.168.1.245/miq_request/show/1000000000125
Thank you,
Virtualization Infrastructure Team
The approving user also receives an email:
Approver,
An automation request received from [email protected] is pending.
Request was not auto-approved.
For more information you can go to: https://192.168.1.245/miq_request/show/1000000000125
Thank you,
Virtualization Infrastructure Team
Clicking the link takes us to an approval page, and we can approve the request, which then continues.
For the third call we see that the assertion evaluates to true, but this time we see the valid group profile being used:
Evaluating substituted assertion ["pending_approval" == "pending_approval"]
Following Relationship [miqaedb:/Automation/Profile/Bit63Group_vm_user#get_auto...
This group's profile auto-approves the automation request, and the Test instance is succesfully run:
Q-task_id([automation_task_1000000000186]) <AEMethod test> Calling the test method was successful!
Success!