Task Execution - Using another hostname as an input parameter?

Problem:
I want to create a job template which accepts 1 input as a parameter - an another host which is already added to Foreman. Simple as That…

I configured my input as following:
image

Template Code:
echo <%= input('hostname') %>

Job execution, I can pick hostname from the list as expected, this is what I want to achieve.

Job STDOUT:

1: > 24
2: > Exit status: 0

Now, why it prints selected host ID, rather than hostname/name ?
I also tried to use:
echo <%= input('hostname').name %>
But it seems for some reason it’s not a safe method, how to make it safe? I really need that.

Kind regards,

Foreman and Proxy versions:
3.13

Distribution and version:
Alma Linux 9.4

Hello I figured this out in Foreman 3.13 by disabling Safemode rendering in the gui.
In the task I used following syntax:

myvariable="<%=  target_host_object = Host.find(input('target_host')) %>"
selectedHostname="<%= target_host_object.name.split('.').first %>"
echo "Selected Host: $selectedHostname"

In another environment i am running Foreman 3.12 and it is not possible to turn off Safemode rendering in the gui. It says: “This setting is defined in the configuration file and is read-only”. Okay, so how to disable this in the configuraiton file? Which configuration file? I guess foreman’s settings.yaml?

I tried to do that by adding:

:safemode_render:
  :enabled: false
:safemode_rendering: false

But it doesn’t work. How to disable safemode in Foreman 3.12?

I am wondering if there’s another way of achieving this wihtout disabling the safe mode?
Why by default it prints ID of an element not the element itself?
It doesn’t make sense, as most people don’t use the element IDs in their jobs, but real values, like hostname in this case.

Assuming you have the input configured as shown on the screenshot in your original post, could you try input_resource('hostname').name?

Hello

It fails with:

Failed to initialize: RuntimeError - Failed rendering template: error during rendering: undefined method ‘#id’ for String::Jail (String)

Could you show the exact template that you used?

Hey, it worked. I am not sure why it failed last time, but it worked now, so thank you for providing me a correct syntax.

1. Job template code:

2. Job template input:

3. Job tab:

4. Job execution
I can select hosts from the list

5. Output:
image

Regarding IDs, why in the screenshot #4 it uses target ID (171) not a hostname? I wouldn’t mind but when we go to the Monitor / Jobs all I can see is ID starting with 171, instead of the hostname. How it can be useful information for a person who checks the Job invocations page? 171 doesn’t tell much…

Moreover, job description. Is it possible somehow to add input value, which is hostname in this case:
input_resource('hostname').name
into the description?

Glad that’s sorted out, the last error felt a bit off.

I vaguely recall us using names in the past and running into an issue with the rerun request being too big to process if you had thousands of hosts, using this form is probably the most space efficient way of how we can match hosts, even though it is not exactly human readable. But that’s pretty distant past.

No, sadly that’s no possible. The description currently only does simple string replacement.

If you don’t mind me asking, what are you trying to accomplish?

Hey

But that’s pretty distant past.

So is it likely to be changed in the future?

If you don’t mind me asking, what are you trying to accomplish?

I need to execute tasks (shell scripts which execute another things) only from certain servers, let’s call them “Management Servers” which have all dependencies installed etc so they are able to take actions on another servers which by the way are added to foreman too.
In other words:
Management Server → e.g. ping with argument Server A → Server A

This job needs to be executed from Management Server, not Server A.
It basically means that job needs to be scheduled from Management Server in Foreman, not the target itself (Server A).

I was asking about possible description change because right now I don’t have information at all about target, only the ID of the management server which is not helpful as well.

I was asking about possible description change because right now I don’t have information at all about target, only the ID of the management server which is not helpful as well.

Is it possible to create a plugin which changes that?
Can you tell me where the job description is defined in the code?

Kind regards

I wouldn’t necessarily put it that way. I don’t recall that many requests about changing this, but that doesn’t mean it can’t be done.

It should be possible, but it would be easier to change it directly in remote execution. As in run the description through the same template-rendering pipeline as everything else.

Here you go foreman_remote_execution/app/models/job_invocation.rb at master · theforeman/foreman_remote_execution · GitHub

Here you go foreman_remote_execution/app/models/job_invocation.rb at master · theforeman/foreman_remote_execution · GitHub

Thank you! Let me try :slight_smile:

1 Like

Hello. I figured this out. I am not a ruby expert, on the contrary, I’ve never used it before Foreman so perhaps code can look better. But, it works, I haven’t noticed any performance issues as well.

Here it is.

1. Displaying Hostname, instead of ‘Search Query’ (host id) column in the Job invocations page:
From:


To:

So to have a real hostname on which task was executed you need to:

a) Open:
/app/helpers/job_invocations_helper.rb

Add following method:


  def display_search_query(query)
    if query =~ /id\s*\^\s*\((\d+)\)/
      host_id = $1.to_i
      host = Host.find_by_id(host_id)
      return host ? host.name.split('.').first : query
    end
    query
  end

b) Open following file:
/app/views/job_invocations/index.html.erb
change 24 line from:
<td><%= trunc_with_tooltip(invocation.targeting.search_query, 15) %></td>
to:
<td><%= trunc_with_tooltip(display_search_query(invocation.targeting.search_query)) %></td>
c) Restart foreman
systemctl restart foreman

2. Displaying an argument in the job description page, like Host Resource.
When your job template uses a Host Resource as an argument, and you want to display this argument in the desription:


like this:

a) Open:
/app/models/job_invocation.rb

b) Modify generate_description method as following:

def generate_description
  template_invocation = pattern_template_invocations.first
  input_hash = template_invocation.input_values.reduce({}) do |h, v|
    value = v.value
    value = '*' * 3 if v.template_input.respond_to?(:hidden_value) && v.template_input.hidden_value?
    h.update("%{#{v.template_input.name}}" => value)
  end
  input_hash.update("%{job_category}" => job_category)
  input_hash.update("%{template_name}" => template_invocation.template.name)

  # Get the list of targeted hostnames, not used
#  server_names = targeting.hosts.map(&:name).join(', ')
#  input_hash.update("%{server_name}" => server_names)

  # Fetch the user-provided Host resource input
  user_host_input = template_invocation.input_values.find do |v|
    v.template_input.value_type == 'resource' && v.template_input.resource_type == 'Host'
  end

  # Get the hostname from the user input
  if user_host_input
    selected_host = Host.find_by_id(user_host_input.value)  # Assuming value contains the host ID
    input_hash.update("%{user_selected_host}" => selected_host ? selected_host.name : 'Unknown')
  else
    input_hash.update("%{user_selected_host}" => 'None')
  end
  input_hash.default = "''"
  self.description = description_format.gsub(/%{[^}]+}/) { |key| input_hash[key] }
  self.description = self.description[0..(JobInvocation.columns_hash['description'].limit - 1)]
end

c) Then in the job description format add the following:

d) Restart Foreman
systemctl restart foreman