List only userowned VLAN


#1

Hi there

I have the following scenario:
Each user have two VLANs for his own use and should choose one of them during the VM provisioning Service Dialogue. At the moment the user can see all VLANs from vSphere. Is there any way that he can only see only his VLANs?

VLAN Naming example:
VLAN_A_johndoe
VLAN_B_johndoe
VLAN_A_chris
VLAN_B_chris

I have created a method, which lists all available VLANs from the vSphere with the following Script. Is there any way to get only the user owned VLANs by filter something like "vlan = vlan.where(:name=>$username)?

Script

begin

lans = {}
cluster = $evm.vmdb(:ems_cluster).where(:name =>My Cluster).first
cluster.hosts.each do |host|
lans[’!’] = ‘-- select from list --’
host.lans.each do |lan|
lans[“dvs_#{lan.name}”] = “dvs_#{lan.name}”
end
end

list_values = {
‘sort_by’ => :value,
‘data_type’ => :string,
‘required’ => true,
‘values’ => lans
}
list_values.each { |key, value| $evm.object[key] = value }

rescue => err
$evm.log(:error, “[#{err}]\n#{err.backtrace.join(”\n")}")
exit MIQ_STOP
end


#2

Since you already use a dynamic method to populate the dialog-element, can’t you just use a if-statement to filter by username?

begin
  lans = {}
  username = 'chris'
  cluster = $evm.vmdb(:ems_cluster).where(:name =>My Cluster).first
  cluster.hosts.each do |host|
    lans[’!’] = ‘-- select from list --’
    host.lans.each do |lan|
      lans[“dvs_#{lan.name}”] = “dvs_#{lan.name}” if lan.include?(username)
    end
  end

  list_values = {
    ‘sort_by’ => :value,
    ‘data_type’ => :string,
    ‘required’ => true,
    ‘values’ => lans
  }
  list_values.each { |key, value| $evm.object[key] = value }

rescue => err
  $evm.log(:error, “[#{err}]\n#{err.backtrace.join(”\n")}")
  exit MIQ_STOP
end

You also might want to split the “get-all-vlans”-part from the “select-the-subset-of-allowed-lans-for-the-user”-part, like the code below. It is easier to add more rules in the future, if it is a seperate step in the code

  # Get all lans in the cluster
  cluster = $evm.vmdb(:ems_cluster).where(:name =>My Cluster).first
  all_lans = cluster.hosts.map do |host|
    host.lans.map {|lan| "dvs_#{lan.name}"}
  end
  all_lans.flatten().uniq()

  # filter list to only contain lans the user is allowed to see
  all_lans.select!() {|lan| lan.include?(username)}
  
  # convert array to hash
  all_lans.each{|l| lans[l] = l }

#3

Thank you. Is there a way to look out for the currently logged in manageiq-User as a Value?
User-Auth. is LDAP.

I’ve tried it the following way:

username = $evm.object[‘username’]

and after that

lans[“dvs_#{lan.name}”] = “dvs_#{lan.name}” if lans.include?"#{username}"

Doesn’t work so far, as the Dropdown is now empty.

begin
  lans = {}
  username = $evm.object['username']
  cluster = $evm.vmdb(:ems_cluster).where(:name =>'My Cluster').first
  user = $evm.root['user']
  cluster.hosts.each do |host|
    lans['!'] = '-- select from list --'
    host.lans.each do |lan|
      lans["dvs_#{lan.name}"] = "dvs_#{lan.name}" if lans.include?"#{username}"
    end
  end

  list_values = {
    'sort_by'    => :value,
    'data_type'  => :string,
    'required'   => true,
    'values'     => lans
  }
  list_values.each { |key, value| $evm.object[key] = value }

 rescue => err
  $evm.log(:error, "[#{err}]\n#{err.backtrace.join("\n")}")
  exit MIQ_STOP
end

#4

$evm.object['username'] will never return a useful value :slight_smile:

Here is a list of objects accessible through $evm
The content’s of $evm will change, depending on the context it is called (e.g. during service provisioning, vm provisioning, called from a button, called from the API), but most of the time, the thing you need will be there.

From the list, you can see, that there is a $evm.root['user'] object exposed (docu), therefore $evm.root['user'].userid will return the login-name of the current user (note: since Manageiq gaprindashvili/Cloudforms 4.6/the latest version, contains the authentication domain "buc@mycompany.com" instead of just the login name “buc”)

If you have not come accross it yet, you should check out the Book Mastering Cloudforms Automation which covers the Automation Part of ManageIQ and the follow-up book which covers the latest features (including the latest release, ManageIQ Gaprindashvili/Cloudforms 4.6)

Tip 1: Notice, that I am using $evm.root['stuff'] instead of $evm.object['stuff'] to access the objects in $evm , it doesn’t make a difference for dynamic elements, because both are pointing to the same thing, but in more complicated workflows, $evm.object will point to something else as $evm.root

Tip 2: You can use this piece of code on the rails console of the ManageIQ appliance to get a $evm-workspace and test your code interactively

def get_evm
  workspace = MiqAeEngine::MiqAeWorkspaceRuntime.new
  workspace.ae_user = User.where(:userid => 'admin').first
  MiqAeMethodService::MiqAeService.new(workspace)
end
$evm = get_evm

#5

Hi Buc

Ok, thank you for the hint. I have now two VLANs, one named johndoe@domain.com and the other one johndoe. Using now username = $evm.root[‘user’].userid and logged in as User johndoe, but the dropdown is still empty.

What I am missing?

Running the following code:
begin
lans = {}
username = $evm.root[‘user’].userid
cluster = $evm.vmdb(:ems_cluster).where(:name =>‘My Cluster’).first
cluster.hosts.each do |host|
lans[’!’] = ‘-- select from list --’
host.lans.each do |lan|
lans[“dvs_#{lan.name}”] = “dvs_#{lan.name}” if lans.include?(username)
end
end

  list_values = {
    'sort_by'    => :value,
    'data_type'  => :string,
    'required'   => true,
    'values'     => lans
  }
  list_values.each { |key, value| $evm.object[key] = value }

 rescue => err
  $evm.log(:error, "[#{err}]\n#{err.backtrace.join("\n")}")
  exit MIQ_STOP
end

#7

First, I missed, that it is actually lan.name.include?(username) instead of lans.include?(username)
Apart from that the code looks ok. You can always dump the contents of the variables in the automation.log using $evm.log(:info, "DUMP=#{var}")


#8

It’s working :slight_smile:
Thank you!