Specify per-item service catalogue approval type


#1

Hi everyone,

I have a couple of use cases related to ManageIQ service catalogue items, and auto-approve/ pending approvals.

As an example, I may want a couple of OpenStack service catalogue items. One may be for a user to request an extra floating IP, which shouldn’t need any extra approvals (ie; auto-approved). Another may be for a user to request an additional security group, which should need to be approved.

The question is: how can I specify whether a service catalogue item is auto-approved, or pending approval, on a per-item basis?

I’ve had a read of Peter McGowan’s Cloudforms Automation book, and I can override the ManageIQ/Service/Provisioning/StateMachines/ServiceProvision/RequestApproval/Default instance, and have an “approval_type” attribute of “pending” or “auto”. This will set the default value for all service catalogue items.

However, is there a way of specifying “pending” or “auto” on a per-catalogue item basis? Perhaps when the request is created? I’d prefer not to use the REST API, and have this encapsulated within the Automate layer, if possible.

Shane


#2

@gmccullough can you review this question from @jockey10 and forward to a SME if necessary.


#3

One approach would be to tag the Catalog Item and evaluate the tag as part of the approval logic to determine if it should be auto-approved.

@pemcg or @ramrexx Do you have other suggestions or techniques you have used in the past?


#4

Thanks @gmccullough and @jprause.

I’ve been inspecting the objects available to the validate_request method (overrides ManageIQ/Service/Provisioning/StateMachines/ServiceProvisionRequestApproval/validate_request).

From here, it looks like I can access the request object, though I’m not sure it exposes an association to the original service catalogue item (which I would need to check for tags).

eg;

<MiqAeServiceServiceTemplateProvisionRequest:0x2ec2668
@object=#<ServiceTemplateProvisionRequest id: 65000000000056, description: “Provisioning Service [Test Require Approval] from …”, approval_state: “pending_approval”, type: “ServiceTemplateProvisionRequest”, created_on: “2016-05-24 23:39:54”, updated_on: “2016-05-24 23:40:03”, fulfilled_on: nil, requester_id: 65000000000002, requester_name: “User”, request_type: “clone_to_service”, request_state: “pending”, message: “Request was not auto-approved”, status: “Ok”, options: {:dialog=>{“dialog_href”=>"/api/service_templates/65000000000003", “dialog_approver_email”=>“user@lab”}, :src_id=>65000000000003}, userid: “user”, source_id: 65000000000003, source_type: “ServiceTemplate”, destination_id: nil, destination_type: nil, tenant_id: 65000000000001>, @virtual_columns=[“reason”, “region_description”, “region_number”, “request_type_display”, “resource_type”, “stamped_on”, “state”, “v_approved_by”, “v_approved_by_email”], @associations=[“approvers”, “destination”, “miq_request”, “miq_request_tasks”, “requester”, “resource”, “source”, “tenant”]>

I guess I could check the request’s description field for certain keywords, though it’s not a very robust solution.


#5

@jockey10 The source association of the request object will get you the service_template (Catalog Item) that was ordered.


#6

Thanks @gmccullough, that worked perfectly :slight_smile:


#7

For anyone finding this thread, this is my code for the /Service/Provisioning/StateMachines/ServiceProvisionRequestApproval/validate_request method.

Note that this requires:

  • A tag named “auto_approval”

  • A service catalogue item tagged with “auto_approval/yes”

  • The approval_type for the /Service/Provisioning/StateMachines/ServiceProvisionRequestApproval/Default instance set to “pending”

      request = $evm.root['miq_request']
    
      raise "Automation Request not found" if request.nil?
    
      tags = request.source.tags
      tags.each do |tag|
         if tag.include?("auto_approve/yes")
          $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
      end

#8

@jockey10 you could eliminate the need to loop through all of the tags by directly getting the value of the tag category you care about.

As an example you could do something like this (untested)

request = $evm.root['miq_request']

raise 'Automation Request not found' if request.nil?

tag_value = request.source.tags(:auto_approve).first

if tag_value == 'yes'
  $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.root['reason'] = msg
end

#9

Awesome, thanks @bevans !


#10

Your code checks auto_approve, but you’ve named the tag auto_approval, just a heads-up