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:

screenshot

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:

screenshot

The .missing Profile for all other groups is:

screenshot

State Machine

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

screenshot

Instances

The RequireApproval Instance has an approval_type value of require_approval:

screenshot

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:

screenshot

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:

screenshot

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:

screenshot

AutomationRequest_pending

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

screenshot

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!

results matching ""

    No results matching ""